mirror of
https://github.com/wp-graphql/wp-graphql-woocommerce.git
synced 2026-08-14 12:53:44 +02:00
feat: Queries and mutations for shipping zones, tax classes, and tax rates. (#856)
* fix: General bugfixes and improvements * devops: New mutations and types tested and compliance with Linter and PHPStan * chore: hooks added to the mutation resolvers * feat: permission checks added * chore: Linter and compliance met * chore: Linter and compliance met
This commit is contained in:
@@ -271,12 +271,16 @@ class Core_Schema_Filters {
|
||||
$loaders['cart_item'] = &$cart_item_loader;
|
||||
$downloadable_item_loader = new WC_Db_Loader( $context, 'DOWNLOADABLE_ITEM' );
|
||||
$loaders['downloadable_item'] = &$downloadable_item_loader;
|
||||
$tax_class_loader = new WC_Db_Loader( $context, 'TAX_CLASS' );
|
||||
$loaders['tax_class'] = &$tax_class_loader;
|
||||
$tax_rate_loader = new WC_Db_Loader( $context, 'TAX_RATE' );
|
||||
$loaders['tax_rate'] = &$tax_rate_loader;
|
||||
$order_item_loader = new WC_Db_Loader( $context, 'ORDER_ITEM' );
|
||||
$loaders['order_item'] = &$order_item_loader;
|
||||
$shipping_item_loader = new WC_Db_Loader( $context, 'SHIPPING_METHOD' );
|
||||
$loaders['shipping_method'] = &$shipping_item_loader;
|
||||
$shipping_zone_loader = new WC_Db_Loader( $context, 'SHIPPING_ZONE' );
|
||||
$loaders['shipping_zone'] = &$shipping_zone_loader;
|
||||
return $loaders;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ class Type_Registry {
|
||||
Type\WPEnum\Product_Attribute_Enum::register();
|
||||
Type\WPEnum\Attribute_Operator_Enum::register();
|
||||
Type\WPEnum\Currency_Enum::register();
|
||||
Type\WPEnum\Shipping_Location_Type_Enum::register();
|
||||
Type\WPEnum\WC_Setting_Type_Enum::register();
|
||||
|
||||
/**
|
||||
* InputObjects.
|
||||
@@ -67,6 +69,8 @@ class Type_Registry {
|
||||
Type\WPInputObject\Collection_Stats_Where_Args::register();
|
||||
Type\WPInputObject\Product_Attribute_Filter_Input::register();
|
||||
Type\WPInputObject\Product_Attribute_Query_Input::register();
|
||||
Type\WPInputObject\Shipping_Location_Input::register();
|
||||
Type\WPInputObject\WC_Setting_Input::register();
|
||||
|
||||
/**
|
||||
* Interfaces.
|
||||
@@ -112,6 +116,10 @@ class Type_Registry {
|
||||
Type\WPObject\Payment_Token_Types::register();
|
||||
Type\WPObject\Country_State_Type::register();
|
||||
Type\WPObject\Collection_Stats_Type::register();
|
||||
Type\WPObject\Shipping_Zone_Type::register();
|
||||
Type\WPObject\Shipping_Location_Type::register();
|
||||
Type\WPObject\Tax_Class_Type::register();
|
||||
Type\WPObject\WC_Setting_Type::register();
|
||||
|
||||
/**
|
||||
* Object fields.
|
||||
@@ -145,6 +153,8 @@ class Type_Registry {
|
||||
Connection\Tax_Rates::register_connections();
|
||||
Connection\Shipping_Methods::register_connections();
|
||||
Connection\Payment_Gateways::register_connections();
|
||||
Connection\Shipping_Zones::register_connections();
|
||||
Connection\Tax_Classes::register_connections();
|
||||
|
||||
/**
|
||||
* Mutations.
|
||||
@@ -175,6 +185,19 @@ class Type_Registry {
|
||||
Mutation\Coupon_Delete::register_mutation();
|
||||
Mutation\Payment_Method_Delete::register_mutation();
|
||||
Mutation\Payment_Method_Set_Default::register_mutation();
|
||||
Mutation\Shipping_Zone_Create::register_mutation();
|
||||
Mutation\Shipping_Zone_Delete::register_mutation();
|
||||
Mutation\Shipping_Zone_Locations_Clear::register_mutation();
|
||||
Mutation\Shipping_Zone_Locations_Update::register_mutation();
|
||||
Mutation\Shipping_Zone_Method_Add::register_mutation();
|
||||
Mutation\Shipping_Zone_Method_Remove::register_mutation();
|
||||
Mutation\Shipping_Zone_Method_Update::register_mutation();
|
||||
Mutation\Shipping_Zone_Update::register_mutation();
|
||||
Mutation\Tax_Class_Create::register_mutation();
|
||||
Mutation\Tax_Class_Delete::register_mutation();
|
||||
Mutation\Tax_Rate_Create::register_mutation();
|
||||
Mutation\Tax_Rate_Delete::register_mutation();
|
||||
Mutation\Tax_Rate_Update::register_mutation();
|
||||
Mutation\Update_Session::register_mutation();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,6 +174,7 @@ if ( ! class_exists( '\WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce' ) ) :
|
||||
require $include_directory_path . 'model/class-order.php';
|
||||
require $include_directory_path . 'model/class-order-item.php';
|
||||
require $include_directory_path . 'model/class-shipping-method.php';
|
||||
require $include_directory_path . 'model/class-shipping-zone.php';
|
||||
require $include_directory_path . 'model/class-tax-rate.php';
|
||||
|
||||
// Include data loaders class files.
|
||||
@@ -190,13 +191,15 @@ if ( ! class_exists( '\WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce' ) ) :
|
||||
require $include_directory_path . 'data/connection/class-order-item-connection-resolver.php';
|
||||
require $include_directory_path . 'data/connection/class-payment-gateway-connection-resolver.php';
|
||||
require $include_directory_path . 'data/connection/class-product-attribute-connection-resolver.php';
|
||||
require $include_directory_path . 'data/connection/class-product-connection-resolver.php';
|
||||
require $include_directory_path . 'data/connection/class-shipping-method-connection-resolver.php';
|
||||
require $include_directory_path . 'data/connection/class-shipping-zone-connection-resolver.php';
|
||||
require $include_directory_path . 'data/connection/class-tax-class-connection-resolver.php';
|
||||
require $include_directory_path . 'data/connection/class-tax-rate-connection-resolver.php';
|
||||
require $include_directory_path . 'data/connection/class-variation-attribute-connection-resolver.php';
|
||||
|
||||
// Include deprecated resolver trait/class files.
|
||||
require $include_directory_path . 'data/connection/class-coupon-connection-resolver.php';
|
||||
require $include_directory_path . 'data/connection/class-product-connection-resolver.php';
|
||||
require $include_directory_path . 'data/connection/class-customer-connection-resolver.php';
|
||||
|
||||
// Include mutation processor class files.
|
||||
@@ -205,6 +208,8 @@ if ( ! class_exists( '\WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce' ) ) :
|
||||
require $include_directory_path . 'data/mutation/class-coupon-mutation.php';
|
||||
require $include_directory_path . 'data/mutation/class-customer-mutation.php';
|
||||
require $include_directory_path . 'data/mutation/class-order-mutation.php';
|
||||
require $include_directory_path . 'data/mutation/class-shipping-mutation.php';
|
||||
require $include_directory_path . 'data/mutation/class-settings-mutation.php';
|
||||
|
||||
// Include factory class file.
|
||||
require $include_directory_path . 'data/class-factory.php';
|
||||
@@ -239,6 +244,8 @@ if ( ! class_exists( '\WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce' ) ) :
|
||||
require $include_directory_path . 'type/enum/class-attribute-operator-enum.php';
|
||||
require $include_directory_path . 'type/enum/class-product-attribute-enum.php';
|
||||
require $include_directory_path . 'type/enum/class-currency-enum.php';
|
||||
require $include_directory_path . 'type/enum/class-shipping-location-type-enum.php';
|
||||
require $include_directory_path . 'type/enum/class-wc-setting-type-enum.php';
|
||||
|
||||
// Include interface type class files.
|
||||
require $include_directory_path . 'type/interface/class-attribute.php';
|
||||
@@ -282,6 +289,10 @@ if ( ! class_exists( '\WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce' ) ) :
|
||||
require $include_directory_path . 'type/object/class-payment-token-types.php';
|
||||
require $include_directory_path . 'type/object/class-country-state-type.php';
|
||||
require $include_directory_path . 'type/object/class-collection-stats-type.php';
|
||||
require $include_directory_path . 'type/object/class-shipping-location-type.php';
|
||||
require $include_directory_path . 'type/object/class-shipping-zone-type.php';
|
||||
require $include_directory_path . 'type/object/class-tax-class-type.php';
|
||||
require $include_directory_path . 'type/object/class-wc-setting-type.php';
|
||||
|
||||
// Include input type class files.
|
||||
require $include_directory_path . 'type/input/class-cart-item-input.php';
|
||||
@@ -301,6 +312,8 @@ if ( ! class_exists( '\WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce' ) ) :
|
||||
require $include_directory_path . 'type/input/class-collection-stats-where-args.php';
|
||||
require $include_directory_path . 'type/input/class-product-attribute-filter-input.php';
|
||||
require $include_directory_path . 'type/input/class-product-attribute-query-input.php';
|
||||
require $include_directory_path . 'type/input/class-shipping-location-input.php';
|
||||
require $include_directory_path . 'type/input/class-wc-setting-input.php';
|
||||
|
||||
// Include mutation type class files.
|
||||
require $include_directory_path . 'mutation/class-cart-add-fee.php';
|
||||
@@ -329,6 +342,19 @@ if ( ! class_exists( '\WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce' ) ) :
|
||||
require $include_directory_path . 'mutation/class-review-update.php';
|
||||
require $include_directory_path . 'mutation/class-payment-method-delete.php';
|
||||
require $include_directory_path . 'mutation/class-payment-method-set-default.php';
|
||||
require $include_directory_path . 'mutation/class-shipping-zone-create.php';
|
||||
require $include_directory_path . 'mutation/class-shipping-zone-delete.php';
|
||||
require $include_directory_path . 'mutation/class-shipping-zone-locations-clear.php';
|
||||
require $include_directory_path . 'mutation/class-shipping-zone-locations-update.php';
|
||||
require $include_directory_path . 'mutation/class-shipping-zone-method-add.php';
|
||||
require $include_directory_path . 'mutation/class-shipping-zone-method-remove.php';
|
||||
require $include_directory_path . 'mutation/class-shipping-zone-method-update.php';
|
||||
require $include_directory_path . 'mutation/class-shipping-zone-update.php';
|
||||
require $include_directory_path . 'mutation/class-tax-class-create.php';
|
||||
require $include_directory_path . 'mutation/class-tax-class-delete.php';
|
||||
require $include_directory_path . 'mutation/class-tax-rate-create.php';
|
||||
require $include_directory_path . 'mutation/class-tax-rate-delete.php';
|
||||
require $include_directory_path . 'mutation/class-tax-rate-update.php';
|
||||
require $include_directory_path . 'mutation/class-update-session.php';
|
||||
|
||||
// Include connection class/function files.
|
||||
@@ -342,6 +368,8 @@ if ( ! class_exists( '\WPGraphQL\WooCommerce\WP_GraphQL_WooCommerce' ) ) :
|
||||
require $include_directory_path . 'connection/class-product-attributes.php';
|
||||
require $include_directory_path . 'connection/class-products.php';
|
||||
require $include_directory_path . 'connection/class-shipping-methods.php';
|
||||
require $include_directory_path . 'connection/class-shipping-zones.php';
|
||||
require $include_directory_path . 'connection/class-tax-classes.php';
|
||||
require $include_directory_path . 'connection/class-tax-rates.php';
|
||||
require $include_directory_path . 'connection/class-wc-terms.php';
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Connection - Shipping_Zones
|
||||
*
|
||||
* Registers connections to ShippingZone
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Connection
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Connection;
|
||||
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
use WPGraphQL\WooCommerce\Data\Connection\Shipping_Zone_Connection_Resolver;
|
||||
|
||||
/**
|
||||
* Class - Shipping_Zones
|
||||
*/
|
||||
class Shipping_Zones {
|
||||
/**
|
||||
* Registers the various connections from other Types to ShippingZone
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_connections() {
|
||||
// From RootQuery.
|
||||
register_graphql_connection( self::get_connection_config() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an array of $args, this returns the connection config, merging the provided args
|
||||
* with the defaults.
|
||||
*
|
||||
* @param array $args - Connection configuration.
|
||||
* @return array
|
||||
*/
|
||||
public static function get_connection_config( $args = [] ): array {
|
||||
return array_merge(
|
||||
[
|
||||
'fromType' => 'RootQuery',
|
||||
'toType' => 'ShippingZone',
|
||||
'fromFieldName' => 'shippingZones',
|
||||
'connectionArgs' => [],
|
||||
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
|
||||
$resolver = new Shipping_Zone_Connection_Resolver( $source, $args, $context, $info );
|
||||
|
||||
return $resolver->get_connection();
|
||||
},
|
||||
],
|
||||
$args
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of where args.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_connection_args(): array {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Connection - Tax_Classes
|
||||
*
|
||||
* Registers connections to TaxClass
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Connection
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Connection;
|
||||
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
use WPGraphQL\WooCommerce\Data\Connection\Tax_Class_Connection_Resolver;
|
||||
|
||||
/**
|
||||
* Class - TaxClass
|
||||
*/
|
||||
class Tax_Classes {
|
||||
/**
|
||||
* Registers the various connections from other Types to TaxClass
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_connections() {
|
||||
// From RootQuery.
|
||||
register_graphql_connection( self::get_connection_config() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an array of $args, this returns the connection config, merging the provided args
|
||||
* with the defaults.
|
||||
*
|
||||
* @param array $args - Connection configuration.
|
||||
* @return array
|
||||
*/
|
||||
public static function get_connection_config( $args = [] ): array {
|
||||
return array_merge(
|
||||
[
|
||||
'fromType' => 'RootQuery',
|
||||
'toType' => 'TaxClass',
|
||||
'fromFieldName' => 'taxClasses',
|
||||
'connectionArgs' => [],
|
||||
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
|
||||
$resolver = new Tax_Class_Connection_Resolver( $source, $args, $context, $info );
|
||||
|
||||
return $resolver->get_connection();
|
||||
},
|
||||
],
|
||||
$args
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of where args.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_connection_args(): array {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@
|
||||
namespace WPGraphQL\WooCommerce\Data\Connection;
|
||||
|
||||
use WPGraphQL\Data\Connection\AbstractConnectionResolver;
|
||||
use WPGraphQL\WooCommerce\Model\Shipping_Method;
|
||||
use WPGraphQL\WooCommerce\Model\Shipping_Zone;
|
||||
|
||||
/**
|
||||
* Class Shipping_Method_Connection_Resolver
|
||||
@@ -31,6 +33,10 @@ class Shipping_Method_Connection_Resolver extends AbstractConnectionResolver {
|
||||
* @return bool
|
||||
*/
|
||||
public function should_execute() {
|
||||
if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) {
|
||||
graphql_debug( __( 'Permission denied.', 'wp-graphql-woocommerce' ) );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,20 +53,22 @@ class Shipping_Method_Connection_Resolver extends AbstractConnectionResolver {
|
||||
/**
|
||||
* Executes query
|
||||
*
|
||||
* @return array|mixed|string[]
|
||||
* @return int[]
|
||||
*/
|
||||
public function get_query() {
|
||||
// TODO: Implement get_query() method.
|
||||
$wc_shipping = \WC_Shipping::instance();
|
||||
$methods = $wc_shipping->get_shipping_methods();
|
||||
if ( $this->source instanceof Shipping_Zone ) {
|
||||
$methods = $this->source->methods;
|
||||
} else {
|
||||
$wc_shipping = \WC_Shipping::instance();
|
||||
$methods = $wc_shipping->get_shipping_methods();
|
||||
}
|
||||
|
||||
foreach ( $methods as $method ) {
|
||||
$this->loader->prime( $method->id, new Shipping_Method( $method ) );
|
||||
}
|
||||
|
||||
// Get shipping method IDs.
|
||||
$methods = array_map(
|
||||
static function ( $item ) {
|
||||
return $item->id;
|
||||
},
|
||||
array_values( $methods )
|
||||
);
|
||||
$methods = wp_list_pluck( array_values( $methods ), 'id' );
|
||||
|
||||
return $methods;
|
||||
}
|
||||
@@ -68,9 +76,9 @@ class Shipping_Method_Connection_Resolver extends AbstractConnectionResolver {
|
||||
/**
|
||||
* Return an array of items from the query
|
||||
*
|
||||
* @return array|mixed
|
||||
* @return array
|
||||
*/
|
||||
public function get_ids() {
|
||||
public function get_ids_from_query() {
|
||||
return ! empty( $this->query ) ? $this->query : [];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* ConnectionResolver - Shipping_Zone_Connection_Resolver
|
||||
*
|
||||
* Resolves connections to ShippingZone
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Data\Connection
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Data\Connection;
|
||||
|
||||
use WPGraphQL\Data\Connection\AbstractConnectionResolver;
|
||||
use WPGraphQL\WooCommerce\Model\Shipping_Zone;
|
||||
|
||||
/**
|
||||
* Class Shipping_Zone_Connection_Resolver
|
||||
*/
|
||||
class Shipping_Zone_Connection_Resolver extends AbstractConnectionResolver {
|
||||
/**
|
||||
* Return the name of the loader to be used with the connection resolver
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_loader_name() {
|
||||
return 'shipping_zone';
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms if shipping methods should be retrieved.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_execute() {
|
||||
if ( ! \wc_shipping_enabled() ) {
|
||||
graphql_debug( __( 'Shipping is disabled.', 'wp-graphql-woocommerce' ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
|
||||
graphql_debug( __( 'Permission denied.', 'wp-graphql-woocommerce' ) );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates filters for shipping zones.
|
||||
*
|
||||
* @return array|void
|
||||
*/
|
||||
public function get_query_args() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes query
|
||||
*
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function get_query() {
|
||||
/** @var \WC_Shipping_Zone $rest_of_the_world */
|
||||
$rest_of_the_world = \WC_Shipping_Zones::get_zone_by( 'zone_id', 0 );
|
||||
|
||||
$zones = \WC_Shipping_Zones::get_zones();
|
||||
array_unshift( $zones, $rest_of_the_world->get_data() );
|
||||
|
||||
if ( ! empty( $this->query_args['filters'] ) && is_array( $this->query_args['filters'] ) ) {
|
||||
foreach ( $this->query_args['filters'] as $filter ) {
|
||||
$zones = array_filter( $zones, $filter );
|
||||
}
|
||||
}
|
||||
|
||||
return wp_list_pluck( $zones, 'id' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of items from the query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_ids_from_query() {
|
||||
return ! empty( $this->query ) ? $this->query : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates offset.
|
||||
*
|
||||
* @param mixed $offset Decoded query cursor.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_valid_offset( $offset ) {
|
||||
return is_string( $offset );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates shipping zone model.
|
||||
*
|
||||
* @param array $model Shipping zone model.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_valid_model( $model ) {
|
||||
return ! empty( $model ) && $model instanceof Shipping_Zone && 0 !== $model->ID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* ConnectionResolver - Tax_Class_Connection_Resolver
|
||||
*
|
||||
* Resolves connections to TaxClass
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Data\Connection
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Data\Connection;
|
||||
|
||||
use WPGraphQL\Data\Connection\AbstractConnectionResolver;
|
||||
|
||||
/**
|
||||
* Class Tax_Class_Connection_Resolver
|
||||
*/
|
||||
class Tax_Class_Connection_Resolver extends AbstractConnectionResolver {
|
||||
/**
|
||||
* Return the name of the loader to be used with the connection resolver
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_loader_name() {
|
||||
return 'tax_class';
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms if tax classes should be retrieved.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_execute() {
|
||||
if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
|
||||
graphql_debug(
|
||||
__( 'User does not have permission to view tax classes.', 'wp-graphql-woocommerce' )
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates filters for tax classes.
|
||||
*
|
||||
* @return array|void
|
||||
*/
|
||||
public function get_query_args() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes query
|
||||
*
|
||||
* @return array|mixed|string[]
|
||||
*/
|
||||
public function get_query() {
|
||||
$tax_classes = [];
|
||||
|
||||
// Add standard class.
|
||||
$tax_classes[] = [
|
||||
'slug' => 'standard',
|
||||
'name' => __( 'Standard rate', 'wp-graphql-woocommerce' ),
|
||||
];
|
||||
|
||||
$classes = \WC_Tax::get_tax_classes();
|
||||
|
||||
foreach ( $classes as $class ) {
|
||||
$tax_classes[] = [
|
||||
'slug' => sanitize_title( $class ),
|
||||
'name' => $class,
|
||||
];
|
||||
}
|
||||
|
||||
// Cache cart items for later.
|
||||
foreach ( $tax_classes as $tax_class ) {
|
||||
$this->loader->prime( $tax_class['slug'], $tax_class );
|
||||
}
|
||||
|
||||
return wp_list_pluck( $tax_classes, 'slug' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of items from the query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_ids_from_query() {
|
||||
return ! empty( $this->query ) ? $this->query : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates offset.
|
||||
*
|
||||
* @param mixed $offset Decoded query cursor.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_valid_offset( $offset ) {
|
||||
return is_string( $offset );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates tax class model.
|
||||
*
|
||||
* @param array $model Tax class model.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_valid_model( $model ) {
|
||||
return is_array( $model ) && ! empty( $model['name'] ) && ! empty( $model['slug'] );
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,12 @@ class Tax_Rate_Connection_Resolver extends AbstractConnectionResolver {
|
||||
* @return bool
|
||||
*/
|
||||
public function should_execute() {
|
||||
if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
|
||||
graphql_debug(
|
||||
__( 'User does not have permission to view tax rates.', 'wp-graphql-woocommerce' )
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ use GraphQL\Error\UserError;
|
||||
use WPGraphQL\Data\Loader\AbstractDataLoader;
|
||||
use WPGraphQL\WooCommerce\Data\Factory;
|
||||
use WPGraphQL\WooCommerce\Model\Shipping_Method;
|
||||
use WPGraphQL\WooCommerce\Model\Shipping_Zone;
|
||||
use WPGraphQL\WooCommerce\Model\Tax_Rate;
|
||||
|
||||
/**
|
||||
@@ -64,6 +65,9 @@ class WC_Db_Loader extends AbstractDataLoader {
|
||||
case 'DOWNLOADABLE_ITEM':
|
||||
$loader = [ $this, 'load_downloadable_item_from_id' ];
|
||||
break;
|
||||
case 'TAX_CLASS':
|
||||
$loader = [ $this, 'load_tax_class_from_slug' ];
|
||||
break;
|
||||
case 'TAX_RATE':
|
||||
$loader = [ $this, 'load_tax_rate_from_id' ];
|
||||
break;
|
||||
@@ -73,6 +77,9 @@ class WC_Db_Loader extends AbstractDataLoader {
|
||||
case 'SHIPPING_METHOD':
|
||||
$loader = [ $this, 'load_shipping_method_from_id' ];
|
||||
break;
|
||||
case 'SHIPPING_ZONE':
|
||||
$loader = [ $this, 'load_shipping_zone_from_id' ];
|
||||
break;
|
||||
default:
|
||||
/**
|
||||
* For adding custom key types to this loader
|
||||
@@ -126,6 +133,25 @@ class WC_Db_Loader extends AbstractDataLoader {
|
||||
return 0 === $node->get_id() ? $node : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tax class connected the provided IDs.
|
||||
*
|
||||
* @param int $slug - Tax class slug.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function load_tax_class_from_slug( $slug ) {
|
||||
if ( 'standard' === $slug ) {
|
||||
return [
|
||||
'slug' => 'standard',
|
||||
'name' => __( 'Standard rate', 'wp-graphql-woocommerce' ),
|
||||
];
|
||||
} else {
|
||||
$tax_class = \WC_Tax::get_tax_class_by( 'slug', $slug );
|
||||
return is_array( $tax_class ) && ! empty( $tax_class ) ? $tax_class : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tax rate connected the provided IDs.
|
||||
*
|
||||
@@ -139,7 +165,7 @@ class WC_Db_Loader extends AbstractDataLoader {
|
||||
/**
|
||||
* Get tax rate from WooCommerce.
|
||||
*
|
||||
* @var object{
|
||||
* @var \stdClass&object{
|
||||
* tax_rate_id: int,
|
||||
* tax_rate_class: string,
|
||||
* tax_rate_country: string,
|
||||
@@ -151,27 +177,51 @@ class WC_Db_Loader extends AbstractDataLoader {
|
||||
* tax_rate_shipping: bool,
|
||||
* tax_rate_order: int,
|
||||
* tax_rate_city: string,
|
||||
* tax_rate_postcode: string
|
||||
* tax_rate_postcode: string,
|
||||
* tax_rate_postcodes: string,
|
||||
* tax_rate_cities: string
|
||||
* } $rate
|
||||
*/
|
||||
$rate = \WC_Tax::_get_tax_rate( $id, OBJECT );
|
||||
if ( ! empty( $rate ) && is_object( $rate ) ) {
|
||||
$rate->tax_rate_city = '';
|
||||
$rate->tax_rate_postcode = '';
|
||||
$rate->tax_rate_postcodes = '';
|
||||
$rate->tax_rate_cities = '';
|
||||
|
||||
// Get locales from a tax rate.
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
|
||||
$locales = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT location_code, location_type
|
||||
"
|
||||
SELECT location_code, location_type
|
||||
FROM {$wpdb->prefix}woocommerce_tax_rate_locations
|
||||
WHERE tax_rate_id = %d",
|
||||
WHERE tax_rate_id = %d
|
||||
",
|
||||
$rate->tax_rate_id
|
||||
)
|
||||
);
|
||||
|
||||
$cities = [];
|
||||
$postcodes = [];
|
||||
foreach ( $locales as $locale ) {
|
||||
if ( empty( $rate->{'tax_rate_' . $locale->location_type} ) ) {
|
||||
$rate->{'tax_rate_' . $locale->location_type} = [];
|
||||
if ( 'city' === $locale->location_type ) {
|
||||
$cities[] = $locale->location_code;
|
||||
} elseif ( 'postcode' === $locale->location_type ) {
|
||||
$postcodes[] = $locale->location_code;
|
||||
} else {
|
||||
$rate->{'tax_rate_' . $locale->location_type} = $locale->location_code;
|
||||
}
|
||||
$rate->{'tax_rate_' . $locale->location_type}[] = $locale->location_code;
|
||||
}
|
||||
|
||||
if ( ! empty( $cities ) ) {
|
||||
$rate->tax_rate_cities = implode( ';', $cities );
|
||||
$rate->tax_rate_city = end( $cities );
|
||||
}
|
||||
|
||||
if ( ! empty( $postcodes ) ) {
|
||||
$rate->tax_rate_postcodes = implode( ';', $postcodes );
|
||||
$rate->tax_rate_postcode = end( $postcodes );
|
||||
}
|
||||
return new Tax_Rate( $rate );
|
||||
} else {
|
||||
@@ -185,7 +235,7 @@ class WC_Db_Loader extends AbstractDataLoader {
|
||||
* @param int $id - Shipping method ID.
|
||||
*
|
||||
* @return \WPGraphQL\WooCommerce\Model\Shipping_Method
|
||||
* @access public
|
||||
*
|
||||
* @throws \GraphQL\Error\UserError Invalid object.
|
||||
*/
|
||||
public function load_shipping_method_from_id( $id ) {
|
||||
@@ -203,6 +253,26 @@ class WC_Db_Loader extends AbstractDataLoader {
|
||||
return new Shipping_Method( $method );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shipping zone connected the provided IDs.
|
||||
*
|
||||
* @param int $id - Shipping zone IDs.
|
||||
*
|
||||
* @return \WPGraphQL\WooCommerce\Model\Shipping_Zone|null
|
||||
*/
|
||||
public function load_shipping_zone_from_id( $id ) {
|
||||
/** @var \WC_Shipping_Zone|false $zone */
|
||||
$zone = \WC_Shipping_Zones::get_zone( $id );
|
||||
|
||||
if ( false === $zone ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$zone = new Shipping_Zone( $zone );
|
||||
|
||||
return $zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the order item connected the provided IDs.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/**
|
||||
* Defines helper functions for executing mutations related to the WC Settings API.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Data\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Data\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
|
||||
/**
|
||||
* Class - Settings_Mutation
|
||||
*/
|
||||
class Settings_Mutation {
|
||||
/**
|
||||
* Validate a text value for a text based setting.
|
||||
*
|
||||
* @param string $value Value.
|
||||
* @param array $setting Setting.
|
||||
* @return string
|
||||
*/
|
||||
public static function validate_setting_text_field( $value, $setting ) {
|
||||
$value = is_null( $value ) ? '' : $value;
|
||||
return wp_kses_post( trim( stripslashes( $value ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate select based settings.
|
||||
*
|
||||
* @param string $value Value.
|
||||
* @param array $setting Setting.
|
||||
*
|
||||
* @throws \GraphQL\Error\UserError If an invalid setting value was passed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function validate_setting_select_field( $value, $setting ) {
|
||||
if ( array_key_exists( $value, $setting['options'] ) ) {
|
||||
return $value;
|
||||
} else {
|
||||
throw new UserError( __( 'An invalid setting value was passed.', 'wp-graphql-woocommerce' ), 400 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate multiselect based settings.
|
||||
*
|
||||
* @param array $values Values.
|
||||
* @param array $setting Setting.
|
||||
*
|
||||
* @throws \GraphQL\Error\UserError If an invalid setting value was passed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function validate_setting_multiselect_field( $values, $setting ) {
|
||||
if ( empty( $values ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ( ! is_array( $values ) ) {
|
||||
throw new UserError( __( 'An invalid setting value was passed.', 'wp-graphql-woocommerce' ), 400 );
|
||||
}
|
||||
|
||||
$final_values = [];
|
||||
foreach ( $values as $value ) {
|
||||
if ( array_key_exists( $value, $setting['options'] ) ) {
|
||||
$final_values[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $final_values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate image_width based settings.
|
||||
*
|
||||
* @param array $values Values.
|
||||
* @param array $setting Setting.
|
||||
*
|
||||
* @throws \GraphQL\Error\UserError If an invalid setting value was passed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function validate_setting_image_width_field( $values, $setting ) {
|
||||
if ( ! is_array( $values ) ) {
|
||||
throw new UserError( __( 'An invalid setting value was passed.', 'wp-graphql-woocommerce' ), 400 );
|
||||
}
|
||||
|
||||
$current = $setting['value'];
|
||||
if ( isset( $values['width'] ) ) {
|
||||
$current['width'] = intval( $values['width'] );
|
||||
}
|
||||
if ( isset( $values['height'] ) ) {
|
||||
$current['height'] = intval( $values['height'] );
|
||||
}
|
||||
if ( isset( $values['crop'] ) ) {
|
||||
$current['crop'] = (bool) $values['crop'];
|
||||
}
|
||||
return $current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate radio based settings.
|
||||
*
|
||||
* @param string $value Value.
|
||||
* @param array $setting Setting.
|
||||
*
|
||||
* @throws \GraphQL\Error\UserError If an invalid setting value was passed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function validate_setting_radio_field( $value, $setting ) {
|
||||
return self::validate_setting_select_field( $value, $setting );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate checkbox based settings.
|
||||
*
|
||||
* @param string $value Value.
|
||||
* @param array $setting Setting.
|
||||
*
|
||||
* @throws \GraphQL\Error\UserError If an invalid setting value was passed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function validate_setting_checkbox_field( $value, $setting ) {
|
||||
if ( in_array( $value, [ 'yes', 'no' ], true ) ) {
|
||||
return $value;
|
||||
} elseif ( empty( $value ) ) {
|
||||
$value = isset( $setting['default'] ) ? $setting['default'] : 'no';
|
||||
return $value;
|
||||
} else {
|
||||
throw new UserError( __( 'An invalid setting value was passed.', 'wp-graphql-woocommerce' ), 400 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate textarea based settings.
|
||||
*
|
||||
* @param string $value Value.
|
||||
* @param array $setting Setting.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function validate_setting_textarea_field( $value, $setting ) {
|
||||
$value = is_null( $value ) ? '' : $value;
|
||||
return wp_kses(
|
||||
trim( stripslashes( $value ) ),
|
||||
array_merge(
|
||||
[
|
||||
'iframe' => [
|
||||
'src' => true,
|
||||
'style' => true,
|
||||
'id' => true,
|
||||
'class' => true,
|
||||
],
|
||||
],
|
||||
wp_kses_allowed_html( 'post' )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* Defines helper functions for executing mutations related to shipping.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Data\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Data\Mutation;
|
||||
|
||||
/**
|
||||
* Class - Shipping_Mutation
|
||||
*/
|
||||
class Shipping_Mutation {
|
||||
/**
|
||||
* Maps the settings input for insertion.
|
||||
*
|
||||
* @param array<array<string, string>> $settings_input Settings input.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private static function flatten_settings_input( $settings_input ) {
|
||||
$settings = [];
|
||||
foreach ( $settings_input as $setting ) {
|
||||
$settings[ $setting['id'] ] = $setting['value'];
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates settings on a shipping zone method.
|
||||
*
|
||||
* @param int $instance_id Instance ID.
|
||||
* @param \WC_Shipping_Method $method Shipping method data.
|
||||
* @param array $settings_input Settings input.
|
||||
*
|
||||
* @return \WC_Shipping_Method
|
||||
*/
|
||||
public static function set_shipping_zone_method_settings( $instance_id, $method, $settings_input ) {
|
||||
$settings = self::flatten_settings_input( $settings_input );
|
||||
$method->init_instance_settings();
|
||||
$instance_settings = $method->instance_settings;
|
||||
$errors_found = false;
|
||||
foreach ( $method->get_instance_form_fields() as $key => $field ) {
|
||||
if ( isset( $settings[ $key ] ) ) {
|
||||
if ( is_callable( [ Settings_Mutation::class, 'validate_setting_' . $field['type'] . '_field' ] ) ) {
|
||||
$value = Settings_Mutation::{'validate_setting_' . $field['type'] . '_field'}( $settings[ $key ], $field );
|
||||
} else {
|
||||
$value = Settings_Mutation::validate_setting_text_field( $settings[ $key ], $field );
|
||||
}
|
||||
$instance_settings[ $key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
update_option(
|
||||
$method->get_instance_option_key(),
|
||||
apply_filters(
|
||||
'woocommerce_shipping_' . $method->id . '_instance_settings_values', // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
|
||||
$instance_settings,
|
||||
$method
|
||||
)
|
||||
);
|
||||
|
||||
$method->instance_settings = $instance_settings;
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the order of a shipping zone method.
|
||||
*
|
||||
* @param int $instance_id Instance ID.
|
||||
* @param \WC_Shipping_Method $method Shipping method data.
|
||||
* @param int $order Order.
|
||||
*
|
||||
* @return \WC_Shipping_Method
|
||||
*/
|
||||
public static function set_shipping_zone_method_order( $instance_id, $method, $order ) {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
|
||||
"{$wpdb->prefix}woocommerce_shipping_zone_methods",
|
||||
[ 'method_order' => $order ],
|
||||
[ 'instance_id' => $instance_id ]
|
||||
);
|
||||
$method->method_order = $order;
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the enabled status of a shipping zone method.
|
||||
*
|
||||
* @param int $zone_id Zone ID.
|
||||
* @param int $instance_id Instance ID.
|
||||
* @param \WC_Shipping_Method $method Shipping method data.
|
||||
* @param bool $enabled Enabled status.
|
||||
*
|
||||
* @return \WC_Shipping_Method
|
||||
*/
|
||||
public static function set_shipping_zone_method_enabled( $zone_id, $instance_id, $method, $enabled ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", [ 'is_enabled' => $enabled ], [ 'instance_id' => $instance_id ] ) ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery
|
||||
do_action( 'woocommerce_shipping_zone_method_status_toggled', $instance_id, $method->id, $zone_id, $enabled ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
|
||||
$method->enabled = ( true === $enabled ? 'yes' : 'no' );
|
||||
}
|
||||
|
||||
return $method;
|
||||
}
|
||||
}
|
||||
@@ -81,4 +81,32 @@ class Shipping_Method extends Model {
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards function calls to WC_Data sub-class instance.
|
||||
*
|
||||
* @param string $method - function name.
|
||||
* @param array $args - function call arguments.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \BadMethodCallException Method not found on WC data object.
|
||||
*/
|
||||
public function __call( $method, $args ) {
|
||||
if ( \is_callable( [ $this->data, $method ] ) ) {
|
||||
return $this->data->$method( ...$args );
|
||||
}
|
||||
|
||||
$class = self::class;
|
||||
throw new \BadMethodCallException( "Call to undefined method {$method} on the {$class}" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source WC_Data instance
|
||||
*
|
||||
* @return \WC_Shipping_Method
|
||||
*/
|
||||
public function as_WC_Data() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* Model - Shipping_Zone
|
||||
*
|
||||
* This model represents a Shipping Zone.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Model
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Model;
|
||||
|
||||
use GraphQLRelay\Relay;
|
||||
use WPGraphQL\Model\Model;
|
||||
|
||||
/**
|
||||
* Class Shipping_Zone
|
||||
*
|
||||
* @property \WC_Shipping_Zone $data
|
||||
*
|
||||
* @property int $ID
|
||||
* @property string $id
|
||||
* @property int $databaseId
|
||||
* @property string $name
|
||||
* @property string $order
|
||||
* @property object{code: string, type: string}[] $locations
|
||||
* @property \WC_Shipping_Method[] $methods
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Model
|
||||
*/
|
||||
class Shipping_Zone extends Model {
|
||||
/**
|
||||
* Shipping_Zone constructor
|
||||
*
|
||||
* @param \WC_Shipping_Zone $zone Shipping zone object.
|
||||
*/
|
||||
public function __construct( $zone ) {
|
||||
$this->data = $zone;
|
||||
$allowed_restricted_fields = [
|
||||
'isRestricted',
|
||||
'isPrivate',
|
||||
'isPublic',
|
||||
'id',
|
||||
'databaseId',
|
||||
];
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
|
||||
$restricted_cap = apply_filters( 'shipping_zone_restricted_cap', '' );
|
||||
|
||||
parent::__construct( $restricted_cap, $allowed_restricted_fields, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the order item should be considered private.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_private() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Order field resolvers.
|
||||
*/
|
||||
protected function init() {
|
||||
if ( empty( $this->fields ) ) {
|
||||
$this->fields = [
|
||||
'ID' => function () {
|
||||
return $this->data->get_id();
|
||||
},
|
||||
'id' => function () {
|
||||
return ! empty( $this->data->get_id() ) ? Relay::toGlobalId( 'shipping_zone', (string) $this->data->get_id() ) : null;
|
||||
},
|
||||
'databaseId' => function () {
|
||||
return ! empty( $this->ID ) ? $this->ID : null;
|
||||
},
|
||||
'name' => function () {
|
||||
return ! empty( $this->data->get_zone_name() ) ? $this->data->get_zone_name() : null;
|
||||
},
|
||||
'order' => function () {
|
||||
return $this->data->get_zone_order();
|
||||
},
|
||||
'locations' => function () {
|
||||
return $this->data->get_zone_locations();
|
||||
},
|
||||
'methods' => function () {
|
||||
return $this->data->get_shipping_methods();
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards function calls to WC_Data sub-class instance.
|
||||
*
|
||||
* @param string $method - function name.
|
||||
* @param array $args - function call arguments.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \BadMethodCallException Method not found on WC data object.
|
||||
*/
|
||||
public function __call( $method, $args ) {
|
||||
if ( \is_callable( [ $this->data, $method ] ) ) {
|
||||
return $this->data->$method( ...$args );
|
||||
}
|
||||
|
||||
$class = self::class;
|
||||
throw new \BadMethodCallException( "Call to undefined method {$method} on the {$class}" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source WC_Data instance
|
||||
*
|
||||
* @return \WC_Shipping_Zone
|
||||
*/
|
||||
public function as_WC_Data() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
@@ -28,23 +28,27 @@ use WPGraphQL\Model\Model;
|
||||
* tax_rate_shipping: bool,
|
||||
* tax_rate_order: int,
|
||||
* tax_rate_city: string,
|
||||
* tax_rate_postcode: string
|
||||
* tax_rate_postcode: string,
|
||||
* tax_rate_postcodes: string,
|
||||
* tax_rate_cities: string
|
||||
* } $data
|
||||
*
|
||||
* @property int $ID
|
||||
* @property string $id
|
||||
* @property string $databaseId
|
||||
* @property string $country
|
||||
* @property string $state
|
||||
* @property string $city
|
||||
* @property string $postcode
|
||||
* @property string $rate
|
||||
* @property string $name
|
||||
* @property string $priority
|
||||
* @property bool $compound
|
||||
* @property bool $shipping
|
||||
* @property int $order
|
||||
* @property string $class
|
||||
* @property int $ID
|
||||
* @property string $id
|
||||
* @property string $databaseId
|
||||
* @property string $country
|
||||
* @property string $state
|
||||
* @property string $city
|
||||
* @property string $postcode
|
||||
* @property string[] $postcodes
|
||||
* @property string[] $cities
|
||||
* @property string $rate
|
||||
* @property string $name
|
||||
* @property string $priority
|
||||
* @property bool $compound
|
||||
* @property bool $shipping
|
||||
* @property int $order
|
||||
* @property string $class
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Model
|
||||
*/
|
||||
@@ -52,7 +56,7 @@ class Tax_Rate extends Model {
|
||||
/**
|
||||
* Tax_Rate constructor
|
||||
*
|
||||
* @param object{ tax_rate_id: int, tax_rate_class: string, tax_rate_country: string, tax_rate_state: string, tax_rate: string, tax_rate_name: string, tax_rate_priority: int, tax_rate_compound: bool, tax_rate_shipping: bool, tax_rate_order: int, tax_rate_city: string, tax_rate_postcode: string } $rate Tax rate object.
|
||||
* @param object{ tax_rate_id: int, tax_rate_class: string, tax_rate_country: string, tax_rate_state: string, tax_rate: string, tax_rate_name: string, tax_rate_priority: int, tax_rate_compound: bool, tax_rate_shipping: bool, tax_rate_order: int, tax_rate_city: string, tax_rate_postcode: string, tax_rate_postcodes: string, tax_rate_cities: string } $rate Tax rate object.
|
||||
*/
|
||||
public function __construct( $rate ) {
|
||||
$this->data = $rate;
|
||||
@@ -101,10 +105,16 @@ class Tax_Rate extends Model {
|
||||
return ! empty( $this->data->tax_rate_state ) ? $this->data->tax_rate_state : null;
|
||||
},
|
||||
'city' => function () {
|
||||
return ! empty( $this->data->tax_rate_city ) ? $this->data->tax_rate_city : [ '*' ];
|
||||
return ! empty( $this->data->tax_rate_city ) ? $this->data->tax_rate_city : '*';
|
||||
},
|
||||
'postcode' => function () {
|
||||
return ! empty( $this->data->tax_rate_postcode ) ? $this->data->tax_rate_postcode : [ '*' ];
|
||||
return ! empty( $this->data->tax_rate_postcode ) ? $this->data->tax_rate_postcode : '*';
|
||||
},
|
||||
'postcodes' => function () {
|
||||
return ! empty( $this->data->tax_rate_postcodes ) ? explode( ';', $this->data->tax_rate_postcodes ) : [ '*' ];
|
||||
},
|
||||
'cities' => function () {
|
||||
return ! empty( $this->data->tax_rate_cities ) ? explode( ';', $this->data->tax_rate_cities ) : [ '*' ];
|
||||
},
|
||||
'rate' => function () {
|
||||
return ! empty( $this->data->tax_rate ) ? $this->data->tax_rate : null;
|
||||
@@ -116,10 +126,10 @@ class Tax_Rate extends Model {
|
||||
return ! empty( $this->data->tax_rate_priority ) ? $this->data->tax_rate_priority : null;
|
||||
},
|
||||
'compound' => function () {
|
||||
return ! empty( $this->data->tax_rate_compound ) ? $this->data->tax_rate_compound : null;
|
||||
return isset( $this->data->tax_rate_compound ) ? $this->data->tax_rate_compound : null;
|
||||
},
|
||||
'shipping' => function () {
|
||||
return ! empty( $this->data->tax_rate_shipping ) ? $this->data->tax_rate_shipping : null;
|
||||
return isset( $this->data->tax_rate_shipping ) ? $this->data->tax_rate_shipping : null;
|
||||
},
|
||||
'order' => function () {
|
||||
return ! is_null( $this->data->tax_rate_order ) ? absint( $this->data->tax_rate_order ) : null;
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - createShippingZone
|
||||
*
|
||||
* Registers mutation for creating a shipping zone.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
|
||||
/**
|
||||
* Class - Shipping_Zone_Create
|
||||
*/
|
||||
class Shipping_Zone_Create {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'createShippingZone',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'name' => [
|
||||
'type' => [ 'non_null' => 'String' ],
|
||||
'description' => __( 'Name of the shipping zone.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'order' => [
|
||||
'type' => 'Int',
|
||||
'description' => __( 'Order of the shipping zone.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'shippingZone' => [
|
||||
'type' => 'ShippingZone',
|
||||
'resolve' => static function ( $payload, array $args, AppContext $context ) {
|
||||
return $context->get_loader( 'shipping_zone' )->load( $payload['zone_id'] );
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_shipping_enabled() ) {
|
||||
throw new UserError( __( 'Shipping is disabled.', 'wp-graphql-woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to create shipping zones.', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
|
||||
$zone = new \WC_Shipping_Zone( null );
|
||||
$zone->set_zone_name( $input['name'] );
|
||||
|
||||
if ( ! empty( $input['order'] ) ) {
|
||||
$zone->set_zone_order( $input['order'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter zone object before saving.
|
||||
*
|
||||
* @param \WC_Shipping_Zone $zone The response object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$zone = apply_filters( 'graphql_woocommerce_shipping_zone_create', $zone, $input );
|
||||
|
||||
$zone_id = $zone->save();
|
||||
|
||||
if ( 0 === $zone->get_id() ) {
|
||||
throw new UserError( __( 'Failed to create shipping zone.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
return [ 'zone_id' => $zone_id ];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - deleteShippingZone
|
||||
*
|
||||
* Registers mutation for deleting a shipping zone.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
|
||||
/**
|
||||
* Class - Shipping_Zone_Delete
|
||||
*/
|
||||
class Shipping_Zone_Delete {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'deleteShippingZone',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'id' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'The ID of the shipping zone to delete.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'shippingZone' => [
|
||||
'type' => 'ShippingZone',
|
||||
'resolve' => static function ( $payload ) {
|
||||
return $payload['shippingZone'];
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_shipping_enabled() ) {
|
||||
throw new UserError( __( 'Shipping is disabled.', 'wp-graphql-woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'delete' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to delete shipping zones', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
|
||||
$zone_id = $input['id'];
|
||||
/** @var \WC_Shipping_Zone|false $zone */
|
||||
$zone = \WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id );
|
||||
|
||||
if ( false === $zone ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter zone object returned from the GraphQL API.
|
||||
*
|
||||
* @param \WC_Shipping_Zone $zone The response object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$zone = apply_filters( 'graphql_woocommerce_delete_shipping_zone', $zone, $input );
|
||||
|
||||
$object = $context->get_loader( 'shipping_zone' )->load( $zone_id );
|
||||
|
||||
/**
|
||||
* Filter zone model returned from the GraphQL API before deletion.
|
||||
*
|
||||
* @param \Shipping_Zone $object The response object.
|
||||
* @param \WC_Shipping_Zone $zone The zone object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$object = apply_filters( 'graphql_woocommerce_delete_shipping_zone_object', $object, $zone, $input );
|
||||
|
||||
$zone->delete();
|
||||
|
||||
return [ 'shippingZone' => $object ];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - clearShippingZoneLocations
|
||||
*
|
||||
* Registers mutation for removing all registered shipping locations from a shipping zone.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
|
||||
/**
|
||||
* Class - Shipping_Zone_Locations_Clear
|
||||
*/
|
||||
class Shipping_Zone_Locations_Clear {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'clearShippingZoneLocations',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'zoneId' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'The ID of the shipping zone to delete.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'type' => [
|
||||
'type' => 'ShippingLocationTypeEnum',
|
||||
'description' => __( 'The type of location to remove.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'shippingZone' => [
|
||||
'type' => 'ShippingZone',
|
||||
'resolve' => static function ( $payload, array $args, AppContext $context ) {
|
||||
return $context->get_loader( 'shipping_zone' )->load( $payload['zone_id'] );
|
||||
},
|
||||
],
|
||||
'removedLocations' => [
|
||||
'type' => [ 'list_of' => 'ShippingLocation' ],
|
||||
'resolve' => static function ( $payload ) {
|
||||
return ! empty( $payload['removedLocations'] )
|
||||
? array_map(
|
||||
static function ( $location ) {
|
||||
return (object) $location;
|
||||
},
|
||||
$payload['removedLocations'],
|
||||
)
|
||||
: [];
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_shipping_enabled() ) {
|
||||
throw new UserError( __( 'Shipping is disabled.', 'wp-graphql-woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'delete' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to remove shipping locations', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
|
||||
$zone_id = $input['zoneId'];
|
||||
/** @var \WC_Shipping_Zone|false $zone */
|
||||
$zone = \WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id );
|
||||
|
||||
if ( false === $zone ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
if ( 0 === $zone->get_id() ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
$types = [ 'postcode', 'state', 'country', 'continent' ];
|
||||
if ( ! empty( $input['type'] ) ) {
|
||||
$types = [ $input['type'] ];
|
||||
}
|
||||
|
||||
$all_locations = $zone->get_zone_locations();
|
||||
$locations = array_filter(
|
||||
$all_locations,
|
||||
static function ( $location ) use ( $types ) {
|
||||
return in_array( $location->type, $types, true );
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Filter zone object before removing the locations.
|
||||
*
|
||||
* @param \WC_Shipping_Zone $zone The response object.
|
||||
* @param array $locations Locations to be removed.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$zone = apply_filters( 'graphql_woocommerce_shipping_zone_locations_clear', $zone, $locations, $input );
|
||||
|
||||
$zone->clear_locations( $types );
|
||||
$zone->save();
|
||||
|
||||
return [
|
||||
'zone_id' => $zone_id,
|
||||
'removedLocations' => $locations,
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - clearShippingZoneLocations
|
||||
*
|
||||
* Registers mutation for update the registered shipping locations on a shipping zone.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
|
||||
/**
|
||||
* Class - Shipping_Zone_Locations_Update
|
||||
*/
|
||||
class Shipping_Zone_Locations_Update {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'updateShippingZoneLocations',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'zoneId' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'The ID of the shipping zone to delete.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'locations' => [
|
||||
'type' => [ 'list_of' => 'ShippingLocationInput' ],
|
||||
'description' => __( 'The locations to add to the shipping zone.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'shippingZone' => [
|
||||
'type' => 'ShippingZone',
|
||||
'resolve' => static function ( $payload, array $args, AppContext $context ) {
|
||||
return $context->get_loader( 'shipping_zone' )->load( $payload['zone_id'] );
|
||||
},
|
||||
],
|
||||
'locations' => [
|
||||
'type' => [ 'list_of' => 'ShippingLocation' ],
|
||||
'resolve' => static function ( $payload ) {
|
||||
return ! empty( $payload['locations'] )
|
||||
? array_map(
|
||||
static function ( $location ) {
|
||||
return (object) $location;
|
||||
},
|
||||
$payload['locations'],
|
||||
)
|
||||
: [];
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_shipping_enabled() ) {
|
||||
throw new UserError( __( 'Shipping is disabled.', 'wp-graphql-woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to update shipping location', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
|
||||
$zone_id = $input['zoneId'];
|
||||
/** @var \WC_Shipping_Zone|false $zone */
|
||||
$zone = \WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id );
|
||||
|
||||
if ( false === $zone ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
if ( 0 === $zone->get_id() ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
$raw_locations = ! empty( $input['locations'] ) ? $input['locations'] : [];
|
||||
$locations = [];
|
||||
foreach ( $raw_locations as $location ) {
|
||||
$type = ! empty( $location['type'] ) ? $location['type'] : 'country';
|
||||
|
||||
$locations[] = [
|
||||
'type' => $type,
|
||||
'code' => $location['code'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter zone object before add the locations.
|
||||
*
|
||||
* @param \WC_Shipping_Zone $zone The response object.
|
||||
* @param array $locations Locations to be saved.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$zone = apply_filters( 'graphql_woocommerce_shipping_zone_locations_update', $zone, $locations, $input );
|
||||
|
||||
$zone->set_locations( $locations );
|
||||
$zone->save();
|
||||
|
||||
return [
|
||||
'zone_id' => $zone_id,
|
||||
'locations' => $locations,
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - addMethodToShippingZone
|
||||
*
|
||||
* Registers mutation for adding a shipping method to a shipping zone.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
use WPGraphQL\WooCommerce\Data\Mutation\Shipping_Mutation;
|
||||
use WPGraphQL\WooCommerce\Model\Shipping_Method;
|
||||
|
||||
/**
|
||||
* Class - Shipping_Zone_Method_Add
|
||||
*/
|
||||
class Shipping_Zone_Method_Add {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'addMethodToShippingZone',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'zoneId' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'The ID of the shipping zone to delete.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'methodId' => [
|
||||
'type' => [ 'non_null' => 'String' ],
|
||||
'description' => __( 'The ID of the shipping method to add.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'enabled' => [
|
||||
'type' => 'Boolean',
|
||||
'description' => __( 'Whether the shipping method is enabled or not.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'order' => [
|
||||
'type' => 'Int',
|
||||
'description' => __( 'The order of the shipping method.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'settings' => [
|
||||
'type' => [ 'list_of' => 'WCSettingInput' ],
|
||||
'description' => __( 'The settings for the shipping method.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'shippingZone' => [
|
||||
'type' => 'ShippingZone',
|
||||
'resolve' => static function ( $payload, array $args, AppContext $context ) {
|
||||
return $context->get_loader( 'shipping_zone' )->load( $payload['zone_id'] );
|
||||
},
|
||||
],
|
||||
'method' => [
|
||||
'type' => 'ShippingZoneToShippingMethodConnectionEdge',
|
||||
'resolve' => static function ( $payload, array $args, AppContext $context ) {
|
||||
return [
|
||||
// Call the Shipping_Method constructor directly because "$payload['method']" is a non-scalar value.
|
||||
'node' => new Shipping_Method( $payload['method'] ),
|
||||
'source' => $context->get_loader( 'shipping_zone' )->load( $payload['zone_id'] ),
|
||||
];
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_shipping_enabled() ) {
|
||||
throw new UserError( __( 'Shipping is disabled.', 'wp-graphql-woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to add shipping methods', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
|
||||
$method_id = $input['methodId'];
|
||||
$zone_id = $input['zoneId'];
|
||||
/** @var \WC_Shipping_Zone|false $zone */
|
||||
$zone = \WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id );
|
||||
|
||||
if ( false === $zone ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
if ( 0 === $zone->get_id() ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
$instance_id = $zone->add_shipping_method( $method_id );
|
||||
$methods = $zone->get_shipping_methods();
|
||||
$method = false;
|
||||
foreach ( $methods as $method_obj ) {
|
||||
if ( $method_obj->instance_id === $instance_id ) {
|
||||
$method = $method_obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( false === $method ) {
|
||||
throw new UserError( __( 'Failed to add shipping method to shipping zone.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
// Update settings.
|
||||
if ( ! empty( $input['settings'] ) ) {
|
||||
$method = Shipping_Mutation::set_shipping_zone_method_settings( $instance_id, $method, $input['settings'] );
|
||||
}
|
||||
|
||||
// Update order.
|
||||
if ( isset( $input['order'] ) ) {
|
||||
$method = Shipping_Mutation::set_shipping_zone_method_order( $instance_id, $method, $input['order'] );
|
||||
}
|
||||
|
||||
// Update if this method is enabled or not.
|
||||
if ( isset( $input['enabled'] ) ) {
|
||||
$method = Shipping_Mutation::set_shipping_zone_method_enabled( $zone_id, $instance_id, $method, $input['enabled'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter shipping method object before responding.
|
||||
*
|
||||
* @param \WC_Shipping_Method $method The shipping method object.
|
||||
* @param \WC_Shipping_Zone $zone The response object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$method = apply_filters( 'graphql_woocommerce_shipping_zone_method_add', $method, $zone, $input );
|
||||
|
||||
return [
|
||||
'zone_id' => $zone_id,
|
||||
'zone' => $zone,
|
||||
'method' => $method,
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - removeMethodFromShippingZone
|
||||
*
|
||||
* Registers mutation for removing a shipping method from a shipping zone.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
use WPGraphQL\WooCommerce\Model\Shipping_Method;
|
||||
|
||||
/**
|
||||
* Class - Shipping_Zone_Method_Remove
|
||||
*/
|
||||
class Shipping_Zone_Method_Remove {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'removeMethodFromShippingZone',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'zoneId' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'The ID of the shipping zone to delete.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'instanceId' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'Shipping method instance ID', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'shippingZone' => [
|
||||
'type' => 'ShippingZone',
|
||||
'resolve' => static function ( $payload, array $args, AppContext $context ) {
|
||||
return $context->get_loader( 'shipping_zone' )->load( $payload['zone_id'] );
|
||||
},
|
||||
],
|
||||
'removedMethod' => [
|
||||
'type' => 'ShippingZoneToShippingMethodConnectionEdge',
|
||||
'resolve' => static function ( $payload, array $args, AppContext $context ) {
|
||||
return [
|
||||
// Call the Shipping_Method constructor directly because "$payload['method']" is a non-scalar value.
|
||||
'node' => new Shipping_Method( $payload['method'] ),
|
||||
'source' => $context->get_loader( 'shipping_zone' )->load( $payload['zone_id'] ),
|
||||
];
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_shipping_enabled() ) {
|
||||
throw new UserError( __( 'Shipping is disabled.', 'wp-graphql-woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'delete' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to remove shipping methods', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
|
||||
$instance_id = $input['instanceId'];
|
||||
$zone_id = $input['zoneId'];
|
||||
/** @var \WC_Shipping_Zone|false $zone */
|
||||
$zone = \WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id );
|
||||
|
||||
if ( false === $zone ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
if ( 0 === $zone->get_id() ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
$methods = $zone->get_shipping_methods();
|
||||
$method = false;
|
||||
|
||||
foreach ( $methods as $shipping_method ) {
|
||||
if ( $shipping_method->instance_id === $instance_id ) {
|
||||
$method = $shipping_method;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $method ) {
|
||||
throw new UserError( __( 'Invalid shipping method instance ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter shipping method object before it's removed from the shipping zone.
|
||||
*
|
||||
* @param \WC_Shipping_Method $method The shipping method to be deleted.
|
||||
* @param \WC_Shipping_Zone $zone The shipping zone object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$method = apply_filters( 'graphql_woocommerce_shipping_zone_method_add', $method, $zone, $input );
|
||||
|
||||
$zone->delete_shipping_method( $instance_id );
|
||||
|
||||
return [
|
||||
'zone_id' => $zone_id,
|
||||
'zone' => $zone,
|
||||
'method' => $method,
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - updateMethodOnShippingZone
|
||||
*
|
||||
* Registers mutation for update a shipping method on a shipping zone.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
use WPGraphQL\WooCommerce\Data\Mutation\Shipping_Mutation;
|
||||
use WPGraphQL\WooCommerce\Model\Shipping_Method;
|
||||
|
||||
/**
|
||||
* Class - Shipping_Zone_Method_Update
|
||||
*/
|
||||
class Shipping_Zone_Method_Update {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'updateMethodOnShippingZone',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'zoneId' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'The ID of the shipping zone to delete.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'instanceId' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'Shipping method instance ID', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'enabled' => [
|
||||
'type' => 'Boolean',
|
||||
'description' => __( 'Whether the shipping method is enabled or not.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'order' => [
|
||||
'type' => 'Int',
|
||||
'description' => __( 'The order of the shipping method.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'settings' => [
|
||||
'type' => [ 'list_of' => 'WCSettingInput' ],
|
||||
'description' => __( 'The settings for the shipping method.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'shippingZone' => [
|
||||
'type' => 'ShippingZone',
|
||||
'resolve' => static function ( $payload, array $args, AppContext $context ) {
|
||||
return $context->get_loader( 'shipping_zone' )->load( $payload['zone_id'] );
|
||||
},
|
||||
],
|
||||
'method' => [
|
||||
'type' => 'ShippingZoneToShippingMethodConnectionEdge',
|
||||
'resolve' => static function ( $payload, array $args, AppContext $context ) {
|
||||
return [
|
||||
// Call the Shipping_Method constructor directly because "$payload['method']" is a non-scalar value.
|
||||
'node' => new Shipping_Method( $payload['method'] ),
|
||||
'source' => $context->get_loader( 'shipping_zone' )->load( $payload['zone_id'] ),
|
||||
];
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_shipping_enabled() ) {
|
||||
throw new UserError( __( 'Shipping is disabled.', 'wp-graphql-woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to edit shipping methods.', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
$instance_id = $input['instanceId'];
|
||||
$zone_id = $input['zoneId'];
|
||||
/** @var \WC_Shipping_Zone|false $zone */
|
||||
$zone = \WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id );
|
||||
|
||||
if ( false === $zone ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
if ( 0 === $zone->get_id() ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
$methods = $zone->get_shipping_methods();
|
||||
$method = false;
|
||||
|
||||
foreach ( $methods as $shipping_method ) {
|
||||
if ( $shipping_method->instance_id === $instance_id ) {
|
||||
$method = $shipping_method;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $method ) {
|
||||
throw new UserError( __( 'Invalid shipping method instance ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
// Update settings.
|
||||
if ( ! empty( $input['settings'] ) ) {
|
||||
$method = Shipping_Mutation::set_shipping_zone_method_settings( $instance_id, $method, $input['settings'] );
|
||||
}
|
||||
|
||||
// Update order.
|
||||
if ( isset( $input['order'] ) ) {
|
||||
$method = Shipping_Mutation::set_shipping_zone_method_order( $instance_id, $method, $input['order'] );
|
||||
}
|
||||
|
||||
// Update if this method is enabled or not.
|
||||
if ( isset( $input['enabled'] ) ) {
|
||||
$method = Shipping_Mutation::set_shipping_zone_method_enabled( $zone_id, $instance_id, $method, $input['enabled'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter shipping method object before responding.
|
||||
*
|
||||
* @param \WC_Shipping_Method $method The shipping method object.
|
||||
* @param \WC_Shipping_Zone $zone The shipping zone object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$method = apply_filters( 'graphql_woocommerce_shipping_zone_method_update', $method, $zone, $input );
|
||||
|
||||
return [
|
||||
'zone_id' => $zone_id,
|
||||
'zone' => $zone,
|
||||
'method' => $method,
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - updateShippingZone
|
||||
*
|
||||
* Registers mutation for updating a shipping zone.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
|
||||
/**
|
||||
* Class - Shipping_Zone_Update
|
||||
*/
|
||||
class Shipping_Zone_Update {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'updateShippingZone',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'id' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'The ID of the shipping zone to update.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Name of the shipping zone.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'order' => [
|
||||
'type' => 'Int',
|
||||
'description' => __( 'Order of the shipping zone.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'shippingZone' => [
|
||||
'type' => 'ShippingZone',
|
||||
'resolve' => static function ( $payload, array $args, AppContext $context ) {
|
||||
return $context->get_loader( 'shipping_zone' )->load( $payload['zone_id'] );
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_shipping_enabled() ) {
|
||||
throw new UserError( __( 'Shipping is disabled.', 'wp-graphql-woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to edit shipping zones', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
|
||||
$zone_id = $input['id'];
|
||||
/** @var \WC_Shipping_Zone|false $zone */
|
||||
$zone = \WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id );
|
||||
|
||||
if ( false === $zone ) {
|
||||
throw new UserError( __( 'Invalid shipping zone ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
if ( 0 === $zone->get_id() ) {
|
||||
throw new UserError( __( 'The "locations not covered by your other zones" zone cannot be updated.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
$zone_changed = false;
|
||||
|
||||
if ( ! empty( $input['name'] ) ) {
|
||||
$zone->set_zone_name( $input['name'] );
|
||||
$zone_changed = true;
|
||||
}
|
||||
|
||||
if ( ! empty( $input['order'] ) ) {
|
||||
$zone->set_zone_order( $input['order'] );
|
||||
$zone_changed = true;
|
||||
}
|
||||
|
||||
if ( $zone_changed ) {
|
||||
/**
|
||||
* Filter zone object before saving changes.
|
||||
*
|
||||
* @param \WC_Shipping_Zone $zone The response object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$zone = apply_filters( 'graphql_woocommerce_shipping_zone_update', $zone, $input );
|
||||
$zone->save();
|
||||
}
|
||||
|
||||
return [ 'zone_id' => $zone_id ];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - createTaxClass
|
||||
*
|
||||
* Registers mutation for creating a tax class.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
|
||||
/**
|
||||
* Class - Tax_Class_Create
|
||||
*/
|
||||
class Tax_Class_Create {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'createTaxClass',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'name' => [
|
||||
'type' => [ 'non_null' => 'String' ],
|
||||
'description' => __( 'Name of the tax class.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'slug' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Slug of the tax class.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'taxClass' => [
|
||||
'type' => 'TaxClass',
|
||||
'resolve' => static function ( $payload ) {
|
||||
return ! empty( $payload['taxClass'] ) ? $payload['taxClass'] : null;
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'create' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to create tax classes.', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
$name = $input['name'];
|
||||
$slug = ! empty( $input['slug'] ) ? $input['slug'] : '';
|
||||
|
||||
$tax_class = \WC_Tax::create_tax_class( $name, $slug );
|
||||
|
||||
if ( is_wp_error( $tax_class ) ) {
|
||||
throw new UserError( $tax_class->get_error_message() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter tax class object before responding.
|
||||
*
|
||||
* @param array $tax_class The shipping method object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$tax_class = apply_filters( 'graphql_woocommerce_tax_class_create', $tax_class, $input );
|
||||
|
||||
return [ 'taxClass' => $tax_class ];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - deleteTaxClass
|
||||
*
|
||||
* Registers mutation for deleting a tax class.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
|
||||
/**
|
||||
* Class - Tax_Class_Delete
|
||||
*/
|
||||
class Tax_Class_Delete {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'deleteTaxClass',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'slug' => [
|
||||
'type' => [ 'non_null' => 'String' ],
|
||||
'description' => __( 'Slug of the tax class.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'taxClass' => [
|
||||
'type' => 'TaxClass',
|
||||
'resolve' => static function ( $payload ) {
|
||||
return ! empty( $payload['taxClass'] ) ? $payload['taxClass'] : null;
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'delete' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to delete tax classes.', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
$slug = $input['slug'];
|
||||
|
||||
/** @var array|false $tax_class */
|
||||
$tax_class = \WC_Tax::get_tax_class_by( 'slug', $slug );
|
||||
if ( ! $tax_class ) {
|
||||
throw new UserError( __( 'Invalid tax class slug.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Action hook before deleting tax class.
|
||||
*
|
||||
* @param array $tax_class The tax class object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
do_action( 'graphql_woocommerce_before_tax_class_delete', $tax_class, $input );
|
||||
|
||||
$deleted = \WC_Tax::delete_tax_class_by( 'slug', $slug );
|
||||
if ( ! $deleted ) {
|
||||
throw new UserError( __( 'Failed to delete tax class.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter tax class object before responding.
|
||||
*
|
||||
* @param array $tax_class The shipping method object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$tax_class = apply_filters( 'graphql_woocommerce_tax_class_delete', $tax_class, $input );
|
||||
|
||||
return [ 'taxClass' => $tax_class ];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - createTaxRate
|
||||
*
|
||||
* Registers mutation for creating a tax rate.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
|
||||
/**
|
||||
* Class - Tax_Rate_Create
|
||||
*/
|
||||
class Tax_Rate_Create {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'createTaxRate',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => [ self::class, 'mutate_and_get_payload' ],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'country' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Country code for the tax rate.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'state' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'State code for the tax rate.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'postcodes' => [
|
||||
'type' => [ 'list_of' => 'String' ],
|
||||
'description' => __( 'Postcodes for the tax rate.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'cities' => [
|
||||
'type' => [ 'list_of' => 'String' ],
|
||||
'description' => __( 'Cities for the tax rate.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'rate' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Tax rate.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Tax rate name.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'priority' => [
|
||||
'type' => 'Int',
|
||||
'description' => __( 'Tax rate priority.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'compound' => [
|
||||
'type' => 'Boolean',
|
||||
'description' => __( 'Whether the tax rate is compound.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'shipping' => [
|
||||
'type' => 'Boolean',
|
||||
'description' => __( 'Whether the tax rate is applied to shipping.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'order' => [
|
||||
'type' => 'Int',
|
||||
'description' => __( 'Tax rate order.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'class' => [
|
||||
'type' => 'TaxClassEnum',
|
||||
'description' => __( 'Tax rate class.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'taxRate' => [
|
||||
'type' => 'TaxRate',
|
||||
'resolve' => static function ( array $payload, array $args, AppContext $context ) {
|
||||
return $context->get_loader( 'tax_rate' )->load( $payload['tax_rate_id'] );
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @param array $input Mutation input.
|
||||
* @param \WPGraphQL\AppContext $context AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info ResolveInfo instance. Can be
|
||||
* use to get info about the current node in the GraphQL tree.
|
||||
*
|
||||
* @throws \GraphQL\Error\UserError Invalid ID provided | Lack of capabilities.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function mutate_and_get_payload( $input, AppContext $context, ResolveInfo $info ) {
|
||||
$id = ! empty( $input['id'] ) ? $input['id'] : null;
|
||||
$action = ! $id ? 'create' : 'update';
|
||||
$permission = ! $id ? 'create' : 'edit';
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', $permission ) ) {
|
||||
throw new UserError(
|
||||
sprintf(
|
||||
/* translators: %s: permission */
|
||||
__( 'Sorry, you are not allowed to %s tax rates.', 'wp-graphql-woocommerce' ),
|
||||
$permission
|
||||
),
|
||||
\rest_authorization_required_code()
|
||||
);
|
||||
}
|
||||
|
||||
$current = null;
|
||||
if ( ! empty( $id ) ) {
|
||||
/**
|
||||
* @var object{
|
||||
* tax_rate_id: int,
|
||||
* tax_rate_class: string,
|
||||
* tax_rate_country: string,
|
||||
* tax_rate_state: string,
|
||||
* tax_rate: string,
|
||||
* tax_rate_name: string,
|
||||
* tax_rate_priority: int,
|
||||
* tax_rate_compound: bool,
|
||||
* tax_rate_shipping: bool,
|
||||
* tax_rate_order: int,
|
||||
* tax_rate_city: string,
|
||||
* tax_rate_postcode: string,
|
||||
* tax_rate_postcodes: string,
|
||||
* tax_rate_cities: string
|
||||
* } $current
|
||||
*/
|
||||
$current = \WC_Tax::_get_tax_rate( $id, OBJECT );
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$fields = [
|
||||
'country' => 'tax_rate_country',
|
||||
'state' => 'tax_rate_state',
|
||||
'rate' => 'tax_rate',
|
||||
'name' => 'tax_rate_name',
|
||||
'priority' => 'tax_rate_priority',
|
||||
'compound' => 'tax_rate_compound',
|
||||
'shipping' => 'tax_rate_shipping',
|
||||
'order' => 'tax_rate_order',
|
||||
'class' => 'tax_rate_class',
|
||||
];
|
||||
|
||||
foreach ( $fields as $key => $field ) {
|
||||
if ( ! isset( $input[ $key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $current && $current->$field === $input[ $key ] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( $field ) {
|
||||
case 'tax_rate_priority':
|
||||
case 'tax_rate_compound':
|
||||
case 'tax_rate_shipping':
|
||||
case 'tax_rate_order':
|
||||
$data[ $field ] = $input[ $key ];
|
||||
break;
|
||||
case 'tax_rate_class':
|
||||
$data[ $field ] = 'standard' !== $input[ $key ] ? $input[ $key ] : '';
|
||||
break;
|
||||
default:
|
||||
$data[ $field ] = $input[ $key ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter tax rate data before creating/updating.
|
||||
*
|
||||
* @param array $data The tax rate data.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$data = apply_filters( "graphql_woocommerce_before_tax_rate_{$action}_data", $data, $input );
|
||||
|
||||
if ( ! $id ) {
|
||||
$id = \WC_Tax::_insert_tax_rate( $data );
|
||||
} else {
|
||||
\WC_Tax::_update_tax_rate( $id, $data );
|
||||
}
|
||||
|
||||
if ( isset( $input['cities'] ) ) {
|
||||
\WC_Tax::_update_tax_rate_cities( $id, join( ';', $input['cities'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $input['postcodes'] ) ) {
|
||||
\WC_Tax::_update_tax_rate_postcodes( $id, join( ';', $input['postcodes'] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter tax rate object before responding.
|
||||
*
|
||||
* @param object $tax_rate_id The shipping method object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
do_action( "graphql_woocommerce_tax_rate_{$action}", $id, $input );
|
||||
|
||||
return [ 'tax_rate_id' => $id ];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - deleteTaxRate
|
||||
*
|
||||
* Registers mutation for deleting a tax rate.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
|
||||
/**
|
||||
* Class - Tax_Rate_Delete
|
||||
*/
|
||||
class Tax_Rate_Delete {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'deleteTaxRate',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => self::mutate_and_get_payload(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return [
|
||||
'id' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'The ID of the tax rate to update.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'taxRate' => [
|
||||
'type' => 'TaxRate',
|
||||
'resolve' => static function ( $payload ) {
|
||||
return $payload['taxRate'];
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation data modification closure.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function mutate_and_get_payload() {
|
||||
return static function ( $input, AppContext $context, ResolveInfo $info ) {
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'delete' ) ) {
|
||||
throw new UserError( __( 'Sorry, you are not allowed to delete tax rates.', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
global $wpdb;
|
||||
$id = $input['id'];
|
||||
|
||||
$tax = $context->get_loader( 'tax_rate' )->load( $id );
|
||||
if ( ! $tax ) {
|
||||
throw new UserError( __( 'Invalid tax rate ID.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Action before deleting tax rate.
|
||||
*
|
||||
* @param object $tax_rate The tax rate object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
do_action( 'graphql_woocommerce_before_tax_rate_delete', $tax, $input );
|
||||
|
||||
\WC_Tax::_delete_tax_rate( $id );
|
||||
if ( 0 === $wpdb->rows_affected ) {
|
||||
throw new UserError( __( 'Failed to delete tax rate.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter tax rate object before responding.
|
||||
*
|
||||
* @param object $tax_rate The shipping method object.
|
||||
* @param array $input Request input.
|
||||
*/
|
||||
$tax = apply_filters( 'graphql_woocommerce_tax_rate_delete', $tax, $input );
|
||||
|
||||
return [
|
||||
'taxRate' => $tax,
|
||||
];
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Mutation - updateTaxRate
|
||||
*
|
||||
* Registers mutation for updating a tax rate.
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Mutation
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Mutation;
|
||||
|
||||
use WPGraphQL\AppContext;
|
||||
|
||||
/**
|
||||
* Class - Tax_Rate_Update
|
||||
*/
|
||||
class Tax_Rate_Update {
|
||||
/**
|
||||
* Registers mutation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_mutation() {
|
||||
register_graphql_mutation(
|
||||
'updateTaxRate',
|
||||
[
|
||||
'inputFields' => self::get_input_fields(),
|
||||
'outputFields' => self::get_output_fields(),
|
||||
'mutateAndGetPayload' => [ Tax_Rate_Create::class, 'mutate_and_get_payload' ],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation input field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_input_fields() {
|
||||
return array_merge(
|
||||
Tax_Rate_Create::get_input_fields(),
|
||||
[
|
||||
'id' => [
|
||||
'type' => [ 'non_null' => 'Int' ],
|
||||
'description' => __( 'The ID of the tax rate to update.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the mutation output field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_output_fields() {
|
||||
return [
|
||||
'taxRate' => [
|
||||
'type' => 'TaxRate',
|
||||
'resolve' => static function ( array $payload, array $args, AppContext $context ) {
|
||||
return $context->get_loader( 'tax_rate' )->load( $payload['tax_rate_id'] );
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -101,6 +101,17 @@ class Id_Type_Enums {
|
||||
]
|
||||
);
|
||||
|
||||
register_graphql_enum_type(
|
||||
'ShippingZoneIdTypeEnum',
|
||||
[
|
||||
'description' => __( 'The Type of Identifier used to fetch a single Shipping Zone. Default is ID.', 'wp-graphql-woocommerce' ),
|
||||
'values' => [
|
||||
'id' => self::get_value( 'id' ),
|
||||
'database_id' => self::get_value( 'database_id' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
register_graphql_enum_type(
|
||||
'TaxRateIdTypeEnum',
|
||||
[
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* WPEnum Type - ShippingLocationType
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Type\WPEnum
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPEnum;
|
||||
|
||||
/**
|
||||
* Class Shipping_Location_Type_Enum
|
||||
*/
|
||||
class Shipping_Location_Type_Enum {
|
||||
/**
|
||||
* Registers type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register() {
|
||||
register_graphql_enum_type(
|
||||
'ShippingLocationTypeEnum',
|
||||
[
|
||||
'description' => __( 'A Shipping zone location type.', 'wp-graphql-woocommerce' ),
|
||||
'values' => [
|
||||
'COUNTRY' => [ 'value' => 'country' ],
|
||||
'CONTINENT' => [ 'value' => 'continent' ],
|
||||
'STATE' => [ 'value' => 'state' ],
|
||||
'POSTCODE' => [ 'value' => 'postcode' ],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* WPEnum Type - WCSettingTypeEnum
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Type\WPEnum
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPEnum;
|
||||
|
||||
/**
|
||||
* Class WC_Setting_Type_Enum
|
||||
*/
|
||||
class WC_Setting_Type_Enum {
|
||||
/**
|
||||
* Registers type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register() {
|
||||
register_graphql_enum_type(
|
||||
'WCSettingTypeEnum',
|
||||
[
|
||||
'description' => __( 'Type of WC setting.', 'wp-graphql-woocommerce' ),
|
||||
'values' => [
|
||||
'TEXT' => [ 'value' => 'text' ],
|
||||
'EMAIL' => [ 'value' => 'email' ],
|
||||
'NUMBER' => [ 'value' => 'number' ],
|
||||
'COLOR' => [ 'value' => 'color' ],
|
||||
'PASSWORD' => [ 'value' => 'password' ],
|
||||
'TEXTAREA' => [ 'value' => 'textarea' ],
|
||||
'SELECT' => [ 'value' => 'select' ],
|
||||
'MULTI_SELECT' => [ 'value' => 'multi_select' ],
|
||||
'RADIO' => [ 'value' => 'radio' ],
|
||||
'IMAGE_WIDTH' => [ 'value' => 'image_width' ],
|
||||
'CHECKBOX' => [ 'value' => 'checkbox' ],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* WPInputObjectType - ShippingLocationInput
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Type\WPInputObject
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPInputObject;
|
||||
|
||||
/**
|
||||
* Class Shipping_Location_Input
|
||||
*/
|
||||
class Shipping_Location_Input {
|
||||
/**
|
||||
* Registers type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register() {
|
||||
register_graphql_input_type(
|
||||
'ShippingLocationInput',
|
||||
[
|
||||
'description' => __( 'Shipping lines data.', 'wp-graphql-woocommerce' ),
|
||||
'fields' => [
|
||||
'code' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Shipping location code.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'type' => [
|
||||
'type' => 'ShippingLocationTypeEnum',
|
||||
'description' => __( 'Shipping location type.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* WPInputObjectType - WCSettingInput
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Type\WPInputObject
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPInputObject;
|
||||
|
||||
/**
|
||||
* Class WC_Setting_Input
|
||||
*/
|
||||
class WC_Setting_Input {
|
||||
/**
|
||||
* Registers type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register() {
|
||||
register_graphql_input_type(
|
||||
'WCSettingInput',
|
||||
[
|
||||
'description' => __( 'WooCommerce setting input.', 'wp-graphql-woocommerce' ),
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'A unique identifier for the setting.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'value' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Setting value.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -413,6 +413,10 @@ class Root_Query {
|
||||
],
|
||||
],
|
||||
'resolve' => static function ( $source, array $args ) {
|
||||
if ( ! \wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) {
|
||||
throw new UserError( __( 'Sorry, you cannot view shipping methods.', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
|
||||
$id = isset( $args['id'] ) ? $args['id'] : null;
|
||||
$id_type = isset( $args['idType'] ) ? $args['idType'] : 'global_id';
|
||||
|
||||
@@ -434,6 +438,49 @@ class Root_Query {
|
||||
return Factory::resolve_shipping_method( $method_id );
|
||||
},
|
||||
],
|
||||
'shippingZone' => [
|
||||
'type' => 'ShippingZone',
|
||||
'description' => __( 'A shipping zone object', 'wp-graphql-woocommerce' ),
|
||||
'args' => [
|
||||
'id' => [
|
||||
'type' => 'ID',
|
||||
'description' => __( 'The ID for identifying the shipping zone', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'idType' => [
|
||||
'type' => 'ShippingZoneIdTypeEnum',
|
||||
'description' => __( 'Type of ID being used identify shipping zone', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
],
|
||||
'resolve' => static function ( $source, array $args, AppContext $context ) {
|
||||
if ( ! \wc_shipping_enabled() ) {
|
||||
throw new UserError( __( 'Shipping is disabled.', 'wp-graphql-woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
if ( ! \wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
|
||||
throw new UserError( __( 'Permission denied.', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
|
||||
$id = isset( $args['id'] ) ? $args['id'] : null;
|
||||
$id_type = isset( $args['idType'] ) ? $args['idType'] : 'global_id';
|
||||
|
||||
$zone_id = null;
|
||||
switch ( $id_type ) {
|
||||
case 'database_id':
|
||||
$zone_id = $id;
|
||||
break;
|
||||
case 'global_id':
|
||||
default:
|
||||
$id_components = Relay::fromGlobalId( $id );
|
||||
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
|
||||
throw new UserError( __( 'The "id" is invalid', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
$zone_id = $id_components['id'];
|
||||
break;
|
||||
}
|
||||
|
||||
return $context->get_loader( 'shipping_zone' )->load( $zone_id );
|
||||
},
|
||||
],
|
||||
'taxRate' => [
|
||||
'type' => 'TaxRate',
|
||||
'description' => __( 'A tax rate object', 'wp-graphql-woocommerce' ),
|
||||
@@ -448,6 +495,9 @@ class Root_Query {
|
||||
],
|
||||
],
|
||||
'resolve' => static function ( $source, array $args, AppContext $context ) {
|
||||
if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
|
||||
throw new UserError( __( 'Sorry, you cannot view tax rates.', 'wp-graphql-woocommerce' ), \rest_authorization_required_code() );
|
||||
}
|
||||
$id = isset( $args['id'] ) ? $args['id'] : null;
|
||||
$id_type = isset( $args['idType'] ) ? $args['idType'] : 'global_id';
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* WPObject Type - Shipping_Location_Type
|
||||
*
|
||||
* Registers ShippingLocation WPObject type and queries
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Type\WPObject
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPObject;
|
||||
|
||||
/**
|
||||
* Class Shipping_Location_Type
|
||||
*/
|
||||
class Shipping_Location_Type {
|
||||
/**
|
||||
* Registers shipping location type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register() {
|
||||
register_graphql_object_type(
|
||||
'ShippingLocation',
|
||||
[
|
||||
'eagerlyLoadType' => true,
|
||||
'description' => __( 'A Shipping zone object', 'wp-graphql-woocommerce' ),
|
||||
'fields' => [
|
||||
'code' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'The globally unique identifier for the tax rate.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'type' => [
|
||||
'type' => 'ShippingLocationTypeEnum',
|
||||
'description' => __( 'Shipping zone location name.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* WPObject Type - Shipping_Zone_Type
|
||||
*
|
||||
* Registers ShippingZone WPObject type and queries
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Type\WPObject
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPObject;
|
||||
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use WPGraphQL\AppContext;
|
||||
use WPGraphQL\WooCommerce\Data\Connection\Shipping_Method_Connection_Resolver;
|
||||
|
||||
/**
|
||||
* Class Shipping_Zone_Type
|
||||
*/
|
||||
class Shipping_Zone_Type {
|
||||
/**
|
||||
* Registers shipping zone type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register() {
|
||||
register_graphql_object_type(
|
||||
'ShippingZone',
|
||||
[
|
||||
'description' => __( 'A Shipping zone object', 'wp-graphql-woocommerce' ),
|
||||
'interfaces' => [ 'Node' ],
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => [ 'non_null' => 'ID' ],
|
||||
'description' => __( 'The globally unique identifier for the tax rate.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'databaseId' => [
|
||||
'type' => 'Int',
|
||||
'description' => __( 'The ID of the customer in the database', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Shipping zone name.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'order' => [
|
||||
'type' => 'Int',
|
||||
'description' => __( 'Shipping zone order.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'locations' => [
|
||||
'type' => [ 'list_of' => 'ShippingLocation' ],
|
||||
'description' => __( 'Shipping zone locations.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
],
|
||||
'connections' => [
|
||||
'methods' => [
|
||||
'toType' => 'ShippingMethod',
|
||||
'edgeFields' => [
|
||||
'id' => [
|
||||
'type' => [ 'non_null' => 'ID' ],
|
||||
'description' => __( 'The globally unique identifier for the shipping method.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $edge ) {
|
||||
if ( isset( $edge['node'] ) ) {
|
||||
$shipping_method = $edge['node']->as_WC_Data();
|
||||
$instance_id = $shipping_method->instance_id;
|
||||
|
||||
return ! empty( $instance_id ) ? \GraphQLRelay\Relay::toGlobalId( 'shipping_zone_method', $instance_id ) : null;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
],
|
||||
'instanceId' => [
|
||||
'type' => 'Int',
|
||||
'description' => __( 'Shipping method instance ID.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $edge ) {
|
||||
if ( isset( $edge['node'] ) ) {
|
||||
$shipping_method = $edge['node']->as_WC_Data();
|
||||
return $shipping_method->instance_id ?? null;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
],
|
||||
'order' => [
|
||||
'type' => 'Int',
|
||||
'description' => __( 'The order of the shipping method.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $edge ) {
|
||||
if ( isset( $edge['node'] ) ) {
|
||||
$shipping_method = $edge['node']->as_WC_Data();
|
||||
return $shipping_method->method_order ?? null;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
],
|
||||
'enabled' => [
|
||||
'type' => 'Boolean',
|
||||
'description' => __( 'Whether the shipping method is enabled.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $edge ) {
|
||||
if ( isset( $edge['node'] ) ) {
|
||||
/** @var \WC_Shipping_Method $shipping_method */
|
||||
$shipping_method = $edge['node']->as_WC_Data();
|
||||
return $shipping_method->is_enabled();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
],
|
||||
'settings' => [
|
||||
'type' => [ 'list_of' => 'WCSetting' ],
|
||||
'description' => __( 'Shipping method settings.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $edge ) {
|
||||
$settings = [];
|
||||
if ( isset( $edge['node'] ) ) {
|
||||
$shipping_method = $edge['node']->as_WC_Data();
|
||||
$instance_settings = $shipping_method->instance_settings;
|
||||
$fields = $shipping_method->instance_form_fields;
|
||||
foreach ( $fields as $key => $field ) {
|
||||
$default_value = ! empty( $field['default'] ) ? $field['default'] : null;
|
||||
$value = ! empty( $instance_settings[ $key ] ) ? $instance_settings[ $key ] : $default_value;
|
||||
$settings[] = array_merge(
|
||||
$field,
|
||||
[
|
||||
'id' => $key,
|
||||
'value' => $value,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
},
|
||||
],
|
||||
],
|
||||
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
|
||||
$resolver = new Shipping_Method_Connection_Resolver( $source, $args, $context, $info );
|
||||
|
||||
return $resolver->get_connection();
|
||||
},
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* WPObject Type - Tax_Class_Type
|
||||
*
|
||||
* Registers TaxClass WPObject type
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Type\WPObject
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPObject;
|
||||
|
||||
/**
|
||||
* Class Tax_Class_Type
|
||||
*/
|
||||
class Tax_Class_Type {
|
||||
/**
|
||||
* Registers tax class type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register() {
|
||||
register_graphql_object_type(
|
||||
'TaxClass',
|
||||
[
|
||||
'eagerlyLoadType' => true,
|
||||
'description' => __( 'A Tax class object', 'wp-graphql-woocommerce' ),
|
||||
'interfaces' => [ 'Node' ],
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => [ 'non_null' => 'ID' ],
|
||||
'description' => __( 'The globally unique identifier for the tax class.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['slug'] ) ? \GraphQLRelay\Relay::toGlobalId( 'tax_class', $source['slug'] ) : null;
|
||||
},
|
||||
],
|
||||
'slug' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'The globally unique identifier for the tax class.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['slug'] ) ? $source['slug'] : null;
|
||||
},
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Tax class name.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['name'] ) ? $source['name'] : null;
|
||||
},
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -43,12 +43,22 @@ class Tax_Rate_Type {
|
||||
'description' => __( 'State code.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'postcode' => [
|
||||
'type' => [ 'list_of' => 'String' ],
|
||||
'description' => __( 'Postcode/ZIP.', 'wp-graphql-woocommerce' ),
|
||||
'type' => 'String',
|
||||
'description' => __( 'Postcode/ZIP.', 'wp-graphql-woocommerce' ),
|
||||
'deprecationReason' => 'Use "postcodes" instead.',
|
||||
],
|
||||
'city' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'City name.', 'wp-graphql-woocommerce' ),
|
||||
'deprecationReason' => 'Use "cities" instead.',
|
||||
],
|
||||
'postcodes' => [
|
||||
'type' => [ 'list_of' => 'String' ],
|
||||
'description' => __( 'City name.', 'wp-graphql-woocommerce' ),
|
||||
'description' => __( 'Postcodes/ZIPs.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'cities' => [
|
||||
'type' => [ 'list_of' => 'String' ],
|
||||
'description' => __( 'City names.', 'wp-graphql-woocommerce' ),
|
||||
],
|
||||
'rate' => [
|
||||
'type' => 'String',
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* WPObject Type - WC_Setting_Type
|
||||
*
|
||||
* Registers WCSetting WPObject type
|
||||
*
|
||||
* @package WPGraphQL\WooCommerce\Type\WPObject
|
||||
* @since TBD
|
||||
*/
|
||||
|
||||
namespace WPGraphQL\WooCommerce\Type\WPObject;
|
||||
|
||||
/**
|
||||
* Class WC_Setting_Type
|
||||
*/
|
||||
class WC_Setting_Type {
|
||||
/**
|
||||
* Registers WC setting type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register() {
|
||||
register_graphql_object_type(
|
||||
'WCSetting',
|
||||
[
|
||||
'eagerlyLoadType' => true,
|
||||
'description' => __( 'A WC setting object', 'wp-graphql-woocommerce' ),
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => [ 'non_null' => 'ID' ],
|
||||
'description' => __( 'The globally unique identifier for the WC setting.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['id'] ) ? $source['id'] : null;
|
||||
},
|
||||
],
|
||||
'label' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'A human readable label for the setting used in user interfaces.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['title'] ) ? $source['title'] : null;
|
||||
},
|
||||
],
|
||||
'description' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'A human readable description for the setting used in user interfaces.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['description'] ) ? $source['description'] : null;
|
||||
},
|
||||
],
|
||||
'type' => [
|
||||
'type' => 'WCSettingTypeEnum',
|
||||
'description' => __( 'Type of setting.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['type'] ) ? $source['type'] : null;
|
||||
},
|
||||
],
|
||||
'value' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Setting value.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['value'] ) ? $source['value'] : null;
|
||||
},
|
||||
],
|
||||
'default' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Default value for the setting.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['default'] ) ? $source['default'] : null;
|
||||
},
|
||||
],
|
||||
'tip' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Additional help text shown to the user about the setting', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['desc_tip'] ) ? $source['desc_tip'] : null;
|
||||
},
|
||||
],
|
||||
'placeholder' => [
|
||||
'type' => 'String',
|
||||
'description' => __( 'Placeholder text to be displayed in text inputs.', 'wp-graphql-woocommerce' ),
|
||||
'resolve' => static function ( $source, array $args, $context, $info ) {
|
||||
return ! empty( $source['placeholder'] ) ? $source['placeholder'] : null;
|
||||
},
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -17,10 +17,12 @@ class ShippingZoneFactory extends \WP_UnitTest_Factory_For_Thing {
|
||||
public function __construct( $factory = null ) {
|
||||
parent::__construct( $factory );
|
||||
|
||||
$this->default_generation_definitions = [
|
||||
'zone_name' => '',
|
||||
];
|
||||
$this->dummy = Dummy::instance();
|
||||
$this->default_generation_definitions = [
|
||||
'zone_name' => 'Test Shipping Zone ' . $this->dummy->number(),
|
||||
'zone_order' => 0,
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function create_object( $args ) {
|
||||
@@ -60,9 +62,37 @@ class ShippingZoneFactory extends \WP_UnitTest_Factory_For_Thing {
|
||||
}
|
||||
|
||||
public function update_object( $object, $fields ) {
|
||||
if ( ! $object instanceof \WC_Customer && 0 !== absint( $object ) ) {
|
||||
if ( ! $object instanceof \WC_Shipping_Zone && 0 !== absint( $object ) ) {
|
||||
$object = $this->get_object_by_id( $object );
|
||||
}
|
||||
|
||||
if ( ! empty( $fields['countries'] ) ) {
|
||||
foreach ( $fields['countries'] as $country ) {
|
||||
$object->add_location( $country, 'country' );
|
||||
}
|
||||
}
|
||||
if ( ! empty( $fields['states'] ) ) {
|
||||
foreach ( $fields['states'] as $state ) {
|
||||
$object->add_location( $state, 'state' );
|
||||
}
|
||||
}
|
||||
if ( ! empty( $fields['postcode'] ) ) {
|
||||
foreach ( $fields['postcode'] as $postcode ) {
|
||||
$object->add_location( $postcode, 'postcode' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $fields['shipping_method'] ) ) {
|
||||
$object->add_shipping_method( $fields['shipping_method'] );
|
||||
}
|
||||
|
||||
foreach ( $fields as $key => $value ) {
|
||||
if ( is_callable( [ $object, "set_{$key}" ] ) ) {
|
||||
$object->{"set_{$key}"}( $value );
|
||||
}
|
||||
}
|
||||
|
||||
return $object->save();
|
||||
}
|
||||
|
||||
public function get_object_by_id( $id ) {
|
||||
@@ -81,6 +111,11 @@ class ShippingZoneFactory extends \WP_UnitTest_Factory_For_Thing {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function reloadShippingMethods() {
|
||||
\WC_Cache_Helper::get_transient_version( 'shipping', true );
|
||||
WC()->shipping()->load_shipping_methods();
|
||||
}
|
||||
|
||||
public function createLegacyFlatRate( $args = [] ) {
|
||||
$flat_rate_settings = array_merge(
|
||||
[
|
||||
@@ -95,8 +130,7 @@ class ShippingZoneFactory extends \WP_UnitTest_Factory_For_Thing {
|
||||
);
|
||||
update_option( 'woocommerce_flat_rate_settings', $flat_rate_settings );
|
||||
update_option( 'woocommerce_flat_rate', [] );
|
||||
\WC_Cache_Helper::get_transient_version( 'shipping', true );
|
||||
\WC()->shipping()->load_shipping_methods();
|
||||
$this->reloadShippingMethods();
|
||||
|
||||
return 'legacy_flat_rate';
|
||||
}
|
||||
@@ -113,8 +147,7 @@ class ShippingZoneFactory extends \WP_UnitTest_Factory_For_Thing {
|
||||
);
|
||||
update_option( 'woocommerce_free_shipping_settings', $free_shipping_settings );
|
||||
update_option( 'woocommerce_free_shipping', [] );
|
||||
\WC_Cache_Helper::get_transient_version( 'shipping', true );
|
||||
WC()->shipping()->load_shipping_methods();
|
||||
$this->reloadShippingMethods();
|
||||
|
||||
return 'legacy_free_shipping';
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* Factory class for the WooCommerce's tax class data objects.
|
||||
*
|
||||
* @since TBD
|
||||
* @package Tests\WPGraphQL\WooCommerce\Factory
|
||||
*/
|
||||
|
||||
namespace Tests\WPGraphQL\WooCommerce\Factory;
|
||||
|
||||
use Tests\WPGraphQL\WooCommerce\Utils\Dummy;
|
||||
|
||||
/**
|
||||
* Tax Class factory class for testing.
|
||||
*/
|
||||
class TaxClassFactory extends \WP_UnitTest_Factory_For_Thing {
|
||||
public function __construct( $factory = null ) {
|
||||
parent::__construct( $factory );
|
||||
|
||||
$this->default_generation_definitions = [
|
||||
'name' => '',
|
||||
'slug' => '',
|
||||
];
|
||||
$this->dummy = Dummy::instance();
|
||||
}
|
||||
|
||||
public function create_object( $args = [] ) {
|
||||
$name = ! empty( $args['name'] ) ? $args['name'] : 'TaxClassNo' . Dummy::instance()->number();
|
||||
$slug = ! empty( $args['slug'] ) ? $args['slug'] : '';
|
||||
|
||||
$tax_class = \WC_Tax::create_tax_class( $name, $slug );
|
||||
|
||||
if ( is_wp_error( $tax_class ) ) {
|
||||
\codecept_debug( $tax_class->get_error_message() );
|
||||
throw new \Exception( $tax_class->get_error_message() );
|
||||
}
|
||||
|
||||
return $tax_class;
|
||||
}
|
||||
|
||||
public function update_object( $object, $fields ) {
|
||||
throw new \Exception( 'You doing it wrong. You can only create or delete tax classes.' );
|
||||
}
|
||||
|
||||
public function get_object_by_id( $slug ) {
|
||||
$tax_class = \WC_Tax::get_tax_class_by( 'slug', $slug );
|
||||
if ( ! $tax_class ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( is_wp_error( $tax_class ) ) {
|
||||
\codecept_debug( $tax_class->get_error_message() );
|
||||
return null;
|
||||
}
|
||||
|
||||
return $tax_class;
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@ class WooGraphQLTestCase extends \Tests\WPGraphQL\TestCase\WPGraphQLTestCase {
|
||||
'Coupon',
|
||||
'Customer',
|
||||
'ShippingZone',
|
||||
'TaxClass',
|
||||
'TaxRate',
|
||||
'Order',
|
||||
'Refund',
|
||||
|
||||
@@ -2,24 +2,10 @@
|
||||
|
||||
use GraphQLRelay\Relay;
|
||||
|
||||
class ShippingMethodQueriesTest extends \Codeception\TestCase\WPTestCase {
|
||||
private $shop_manager;
|
||||
private $customer;
|
||||
private $method;
|
||||
private $helper;
|
||||
class ShippingMethodQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->shop_manager = $this->factory->user->create( [ 'role' => 'shop_manager' ] );
|
||||
$this->customer = $this->factory->user->create( [ 'role' => 'customer' ] );
|
||||
$this->helper = $this->getModule( '\Helper\Wpunit' )->shipping_method();
|
||||
$this->method = 'flat_rate';
|
||||
}
|
||||
|
||||
// tests
|
||||
public function testShippingMethodQueryAndArgs() {
|
||||
$id = Relay::toGlobalId( 'shipping_method', $this->method );
|
||||
$id = Relay::toGlobalId( 'shipping_method', 'flat_rate' );
|
||||
|
||||
$query = '
|
||||
query( $id: ID!, $idType: ShippingMethodIdTypeEnum ) {
|
||||
@@ -35,61 +21,46 @@ class ShippingMethodQueriesTest extends \Codeception\TestCase\WPTestCase {
|
||||
/**
|
||||
* Assertion One
|
||||
*
|
||||
* Test "ID" ID type.
|
||||
* Confirm permission check is working
|
||||
*/
|
||||
$variables = [
|
||||
'id' => $id,
|
||||
'idType' => 'ID',
|
||||
];
|
||||
$actual = graphql(
|
||||
[
|
||||
'query' => $query,
|
||||
'variables' => $variables,
|
||||
]
|
||||
);
|
||||
$expected = [ 'data' => [ 'shippingMethod' => $this->helper->print_query( $this->method ) ] ];
|
||||
$variables = [ 'id' => $id ];
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
// use --debug flag to view.
|
||||
codecept_debug( $actual );
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
$this->assertEquals( $expected, $actual );
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
/**
|
||||
* Assertion Two
|
||||
*
|
||||
* Test "ID" ID type.
|
||||
*/
|
||||
$variables = [ 'id' => $id ];
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedField( 'shippingMethod.id', $id ),
|
||||
$this->expectedField( 'shippingMethod.databaseId', 'flat_rate' ),
|
||||
$this->expectedField( 'shippingMethod.title', self::NOT_NULL ),
|
||||
$this->expectedField( 'shippingMethod.description', self::NOT_NULL ),
|
||||
];
|
||||
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
|
||||
/**
|
||||
* Assertion Three
|
||||
*
|
||||
* Test "DATABASE_ID" ID type.
|
||||
*/
|
||||
$variables = [
|
||||
'id' => $this->method,
|
||||
'idType' => 'DATABASE_ID',
|
||||
];
|
||||
$actual = graphql(
|
||||
[
|
||||
'query' => $query,
|
||||
'variables' => $variables,
|
||||
]
|
||||
);
|
||||
$expected = [ 'data' => [ 'shippingMethod' => $this->helper->print_query( $this->method ) ] ];
|
||||
$variables = [ 'id' => 'flat_rate', 'idType' => 'DATABASE_ID' ];
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
// use --debug flag to view.
|
||||
codecept_debug( $actual );
|
||||
|
||||
$this->assertEquals( $expected, $actual );
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testShippingMethodsQuery() {
|
||||
$wc_shipping = WC_Shipping::instance();
|
||||
$methods = array_values(
|
||||
array_map(
|
||||
static function ( $method ) {
|
||||
return [ 'id' => Relay::toGlobalId( 'shipping_method', $method->id ) ];
|
||||
},
|
||||
$wc_shipping->get_shipping_methods()
|
||||
)
|
||||
);
|
||||
|
||||
$query = '
|
||||
query shippingMethodsQuery {
|
||||
query {
|
||||
shippingMethods {
|
||||
nodes {
|
||||
id
|
||||
@@ -98,17 +69,31 @@ class ShippingMethodQueriesTest extends \Codeception\TestCase\WPTestCase {
|
||||
}
|
||||
';
|
||||
|
||||
/**
|
||||
* Assertion One
|
||||
*
|
||||
* Confirm permission check is working
|
||||
*/
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$this->assertQuerySuccessful( $response, [ $this->expectedField( 'shippingMethods.nodes', self::IS_FALSY ) ] );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
/**
|
||||
* Assertion One
|
||||
*
|
||||
* Tests query
|
||||
*/
|
||||
$actual = do_graphql_request( $query, 'shippingMethodQuery' );
|
||||
$expected = [ 'data' => [ 'shippingMethods' => [ 'nodes' => $methods ] ] ];
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$expected = array_map(
|
||||
function( $method ) {
|
||||
return $this->expectedField( 'shippingMethods.nodes.#.id', $this->toRelayId( 'shipping_method', $method->id ) );
|
||||
},
|
||||
array_values( WC_Shipping::instance()->get_shipping_methods() )
|
||||
);
|
||||
|
||||
|
||||
// use --debug flag to view.
|
||||
codecept_debug( $actual );
|
||||
|
||||
$this->assertEquals( $expected, $actual );
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,676 @@
|
||||
<?php
|
||||
|
||||
class ShippingZoneMutationsTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
|
||||
public function testCreateShippingZoneMutation() {
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: CreateShippingZoneInput!) {
|
||||
createShippingZone(input: $input) {
|
||||
shippingZone {
|
||||
id
|
||||
name
|
||||
order
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'name' => 'Test Shipping Zone',
|
||||
'order' => 0
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
// Confirm permissions error.
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as admin and re-execute expecting success.
|
||||
$this->loginAsShopManager();
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'createShippingZone.shippingZone',
|
||||
[
|
||||
$this->expectedField( 'id', self::NOT_NULL ),
|
||||
$this->expectedField( 'name', 'Test Shipping Zone' ),
|
||||
$this->expectedField( 'order', 0 ),
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testUpdateShippingZoneMutation() {
|
||||
// Create a shipping zone.
|
||||
$shipping_zone_id = $this->factory->shipping_zone->create(
|
||||
[
|
||||
'zone_name' => 'Test Shipping Zone',
|
||||
'zone_order' => 0,
|
||||
]
|
||||
);
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: UpdateShippingZoneInput!) {
|
||||
updateShippingZone(input: $input) {
|
||||
shippingZone {
|
||||
id
|
||||
databaseId
|
||||
name
|
||||
order
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'id' => $shipping_zone_id,
|
||||
'name' => 'Updated Shipping Zone',
|
||||
'order' => 1
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
// Confirm permissions error.
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as admin and re-execute expecting success.
|
||||
$this->loginAsShopManager();
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'updateShippingZone.shippingZone',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zone_id ) ),
|
||||
$this->expectedField( 'databaseId', $shipping_zone_id ),
|
||||
$this->expectedField( 'name', 'Updated Shipping Zone' ),
|
||||
$this->expectedField( 'order', 1 ),
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testDeleteShippingZoneMutation() {
|
||||
// Create a shipping zone.
|
||||
$shipping_zone = $this->factory->shipping_zone->create_and_get();
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: DeleteShippingZoneInput!) {
|
||||
deleteShippingZone(input: $input) {
|
||||
shippingZone {
|
||||
id
|
||||
databaseId
|
||||
name
|
||||
order
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'id' => $shipping_zone->get_id()
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
// Confirm permissions error.
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as admin and re-execute expecting success.
|
||||
$this->loginAsShopManager();
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'deleteShippingZone.shippingZone',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zone->get_id() ) ),
|
||||
$this->expectedField( 'databaseId', $shipping_zone->get_id() ),
|
||||
$this->expectedField( 'name', $shipping_zone->get_zone_name() ),
|
||||
$this->expectedField( 'order', $shipping_zone->get_zone_order() ),
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testUpdateShippingZoneLocationsMutation() {
|
||||
// Create a shipping zone.
|
||||
$shipping_zone_id = $this->factory->shipping_zone->create();
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: UpdateShippingZoneLocationsInput!) {
|
||||
updateShippingZoneLocations(input: $input) {
|
||||
shippingZone {
|
||||
id
|
||||
locations {
|
||||
code
|
||||
type
|
||||
}
|
||||
}
|
||||
locations {
|
||||
code
|
||||
type
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'zoneId' => $shipping_zone_id,
|
||||
'locations' => [
|
||||
[
|
||||
'code' => 'US',
|
||||
],
|
||||
[
|
||||
'code' => 'CALIFORNIA',
|
||||
'type' => 'STATE',
|
||||
],
|
||||
[
|
||||
'code' => '12345',
|
||||
'type' => 'POSTCODE',
|
||||
],
|
||||
[
|
||||
'code' => 'NA',
|
||||
'type' => 'CONTINENT',
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
// Confirm permissions error.
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as admin and re-execute expecting success.
|
||||
$this->loginAsShopManager();
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'updateShippingZoneLocations.shippingZone',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zone_id ) ),
|
||||
$this->expectedObject(
|
||||
'locations.0',
|
||||
[
|
||||
$this->expectedField( 'code', 'US' ),
|
||||
$this->expectedField( 'type', 'COUNTRY' )
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'locations.1',
|
||||
[
|
||||
$this->expectedField( 'code', 'CALIFORNIA' ),
|
||||
$this->expectedField( 'type', 'STATE' )
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'locations.2',
|
||||
[
|
||||
$this->expectedField( 'code', '12345' ),
|
||||
$this->expectedField( 'type', 'POSTCODE' )
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'locations.3',
|
||||
[
|
||||
$this->expectedField( 'code', 'NA' ),
|
||||
$this->expectedField( 'type', 'CONTINENT' )
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'updateShippingZoneLocations.locations.0',
|
||||
[
|
||||
$this->expectedField( 'code', 'US' ),
|
||||
$this->expectedField( 'type', 'COUNTRY' )
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'updateShippingZoneLocations.locations.1',
|
||||
[
|
||||
$this->expectedField( 'code', 'CALIFORNIA' ),
|
||||
$this->expectedField( 'type', 'STATE' )
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'updateShippingZoneLocations.locations.2',
|
||||
[
|
||||
$this->expectedField( 'code', '12345' ),
|
||||
$this->expectedField( 'type', 'POSTCODE' )
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'updateShippingZoneLocations.locations.3',
|
||||
[
|
||||
$this->expectedField( 'code', 'NA' ),
|
||||
$this->expectedField( 'type', 'CONTINENT' )
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testClearShippingZoneLocationsMutation() {
|
||||
// Create a shipping zone.
|
||||
$shipping_zone = $this->factory->shipping_zone->create_and_get();
|
||||
|
||||
// Add a location to the shipping zone.
|
||||
$shipping_zone->add_location( 'US', 'country' );
|
||||
$shipping_zone->save();
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: ClearShippingZoneLocationsInput!) {
|
||||
clearShippingZoneLocations(input: $input) {
|
||||
shippingZone {
|
||||
id
|
||||
locations {
|
||||
code
|
||||
}
|
||||
}
|
||||
removedLocations {
|
||||
code
|
||||
type
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [ 'zoneId' => $shipping_zone->get_id() ]
|
||||
];
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
// Confirm permissions error.
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as admin and re-execute expecting success.
|
||||
$this->loginAsShopManager();
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'clearShippingZoneLocations.shippingZone',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zone->get_id() ) ),
|
||||
$this->expectedField( 'locations', self::IS_FALSY )
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'clearShippingZoneLocations.removedLocations.0',
|
||||
[
|
||||
$this->expectedField( 'code', 'US' ),
|
||||
$this->expectedField( 'type', 'COUNTRY' )
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testAddMethodToShippingZoneMutation() {
|
||||
// Create a shipping zone.
|
||||
$shipping_zone_id = $this->factory->shipping_zone->create();
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: AddMethodToShippingZoneInput!) {
|
||||
addMethodToShippingZone(input: $input) {
|
||||
shippingZone {
|
||||
id
|
||||
methods {
|
||||
edges {
|
||||
id
|
||||
instanceId
|
||||
order
|
||||
enabled
|
||||
settings {
|
||||
id
|
||||
label
|
||||
description
|
||||
type
|
||||
value
|
||||
default
|
||||
tip
|
||||
placeholder
|
||||
}
|
||||
node {
|
||||
id
|
||||
databaseId
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
method {
|
||||
id
|
||||
instanceId
|
||||
order
|
||||
enabled
|
||||
settings {
|
||||
id
|
||||
label
|
||||
description
|
||||
type
|
||||
value
|
||||
default
|
||||
tip
|
||||
placeholder
|
||||
}
|
||||
node {
|
||||
id
|
||||
databaseId
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'zoneId' => $shipping_zone_id,
|
||||
'methodId' => 'flat_rate',
|
||||
'order' => 0,
|
||||
'enabled' => true,
|
||||
'settings' => [
|
||||
[
|
||||
'id' => 'cost',
|
||||
'value' => '10'
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
// Confirm permissions error.
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as admin and re-execute expecting success.
|
||||
$this->loginAsShopManager();
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'addMethodToShippingZone.shippingZone',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zone_id ) ),
|
||||
$this->expectedNode(
|
||||
'methods.edges',
|
||||
[
|
||||
$this->expectedField( 'id', self::NOT_NULL ),
|
||||
$this->expectedField( 'instanceId', self::NOT_NULL ),
|
||||
$this->expectedField( 'order', 0 ),
|
||||
$this->expectedField( 'enabled', true ),
|
||||
$this->expectedNode(
|
||||
'settings',
|
||||
[
|
||||
$this->expectedField( 'id', 'cost' ),
|
||||
$this->expectedField( 'value', '10' )
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'node',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_method', 'flat_rate' ) ),
|
||||
$this->expectedField( 'databaseId', self::NOT_NULL ),
|
||||
$this->expectedField( 'title', self::NOT_NULL ),
|
||||
]
|
||||
)
|
||||
],
|
||||
0
|
||||
),
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'addMethodToShippingZone.method',
|
||||
[
|
||||
$this->expectedField( 'id', self::NOT_NULL ),
|
||||
$this->expectedField( 'instanceId', self::NOT_NULL ),
|
||||
$this->expectedField( 'order', 0 ),
|
||||
$this->expectedField( 'enabled', true ),
|
||||
$this->expectedNode(
|
||||
'settings',
|
||||
[
|
||||
$this->expectedField( 'id', 'cost' ),
|
||||
$this->expectedField( 'value', '10' )
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'node',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_method', 'flat_rate' ) ),
|
||||
$this->expectedField( 'databaseId', self::NOT_NULL ),
|
||||
$this->expectedField( 'title', self::NOT_NULL ),
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testUpdateMethodOnShippingZoneMutation() {
|
||||
// Create a shipping zone.
|
||||
$shipping_zone = $this->factory->shipping_zone->create_and_get();
|
||||
$instance_id = $shipping_zone->add_shipping_method( 'flat_rate' );
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: UpdateMethodOnShippingZoneInput!) {
|
||||
updateMethodOnShippingZone(input: $input) {
|
||||
shippingZone {
|
||||
id
|
||||
methods {
|
||||
edges {
|
||||
id
|
||||
instanceId
|
||||
order
|
||||
enabled
|
||||
settings {
|
||||
id
|
||||
label
|
||||
description
|
||||
type
|
||||
value
|
||||
default
|
||||
tip
|
||||
placeholder
|
||||
}
|
||||
node {
|
||||
id
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
method {
|
||||
id
|
||||
instanceId
|
||||
order
|
||||
enabled
|
||||
settings {
|
||||
id
|
||||
label
|
||||
description
|
||||
type
|
||||
value
|
||||
default
|
||||
tip
|
||||
placeholder
|
||||
}
|
||||
node {
|
||||
id
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'zoneId' => $shipping_zone->get_id(),
|
||||
'instanceId' => $instance_id,
|
||||
'settings' => [
|
||||
[
|
||||
'id' => 'cost',
|
||||
'value' => '10'
|
||||
]
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
// Confirm permissions error.
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as admin and re-execute expecting success.
|
||||
$this->loginAsShopManager();
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'updateMethodOnShippingZone.shippingZone',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zone->get_id() ) ),
|
||||
$this->expectedNode(
|
||||
'methods.edges',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone_method', $instance_id ) ),
|
||||
$this->expectedField( 'instanceId', $instance_id ),
|
||||
$this->expectedField( 'order', self::NOT_NULL ),
|
||||
$this->expectedField( 'enabled', true ),
|
||||
$this->expectedNode(
|
||||
'settings',
|
||||
[
|
||||
$this->expectedField( 'id', 'cost' ),
|
||||
$this->expectedField( 'value', '10' )
|
||||
]
|
||||
),
|
||||
$this->expectedField( 'node.id', $this->toRelayId( 'shipping_method', 'flat_rate' ) ),
|
||||
],
|
||||
0
|
||||
),
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'updateMethodOnShippingZone.method',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone_method', $instance_id ) ),
|
||||
$this->expectedField( 'instanceId', $instance_id ),
|
||||
$this->expectedField( 'order', self::NOT_NULL ),
|
||||
$this->expectedField( 'enabled', true ),
|
||||
$this->expectedNode(
|
||||
'settings',
|
||||
[
|
||||
$this->expectedField( 'id', 'cost' ),
|
||||
$this->expectedField( 'value', '10' )
|
||||
]
|
||||
),
|
||||
$this->expectedField( 'node.id', $this->toRelayId( 'shipping_method', 'flat_rate' ) ),
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testRemoveMethodFromShippingZoneMutation() {
|
||||
// Create a shipping zone and add the shipping method.
|
||||
$shipping_zone = $this->factory->shipping_zone->create_and_get();
|
||||
$instance_id = $shipping_zone->add_shipping_method( 'flat_rate' );
|
||||
$shipping_method = new \WC_Shipping_Flat_Rate( $instance_id );
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: RemoveMethodFromShippingZoneInput!) {
|
||||
removeMethodFromShippingZone(input: $input) {
|
||||
shippingZone {
|
||||
id
|
||||
methods {
|
||||
edges {
|
||||
order
|
||||
enabled
|
||||
node { id }
|
||||
}
|
||||
}
|
||||
}
|
||||
removedMethod {
|
||||
order
|
||||
enabled
|
||||
node { id }
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'zoneId' => $shipping_zone->get_id(),
|
||||
'instanceId' => $instance_id
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
|
||||
// Confirm permissions error.
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as admin and re-execute expecting success.
|
||||
$this->loginAsShopManager();
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'removeMethodFromShippingZone.shippingZone',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zone->get_id() ) ),
|
||||
$this->expectedField( 'methods.edges', self::IS_FALSY ),
|
||||
]
|
||||
),
|
||||
$this->expectedObject(
|
||||
'removeMethodFromShippingZone.removedMethod',
|
||||
[
|
||||
$this->expectedField( 'enabled', $shipping_method->is_enabled() ),
|
||||
$this->expectedNode(
|
||||
'node',
|
||||
[ $this->expectedField( 'id', $this->toRelayId( 'shipping_method', $shipping_method->id ) ) ]
|
||||
)
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
class ShippingZoneQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
|
||||
public function testShippingZoneQuery() {
|
||||
// Create a shipping zone.
|
||||
$shipping_zone = $this->factory->shipping_zone->create_and_get();
|
||||
|
||||
// Add location.
|
||||
$shipping_zone->add_location( 'US', 'country' );
|
||||
$shipping_zone->save();
|
||||
|
||||
|
||||
// Add shipping method.
|
||||
$instance_id = $shipping_zone->add_shipping_method( 'flat_rate' );
|
||||
$shipping_method = null;
|
||||
foreach ( $shipping_zone->get_shipping_methods() as $method ) {
|
||||
if ( $method->instance_id === $instance_id ) {
|
||||
$shipping_method = $method;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$instance_settings = $shipping_method->instance_settings;
|
||||
$instance_settings['cost'] = 10.00;
|
||||
update_option( $shipping_method->get_instance_option_key(), $instance_settings );
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'query ($id: ID!) {
|
||||
shippingZone(id: $id) {
|
||||
id
|
||||
name
|
||||
order
|
||||
locations {
|
||||
code
|
||||
type
|
||||
}
|
||||
methods {
|
||||
edges {
|
||||
id
|
||||
instanceId
|
||||
order
|
||||
enabled
|
||||
settings {
|
||||
id
|
||||
label
|
||||
description
|
||||
type
|
||||
value
|
||||
default
|
||||
tip
|
||||
placeholder
|
||||
}
|
||||
node {
|
||||
id
|
||||
title
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [ 'id' => $this->toRelayId( 'shipping_zone', $shipping_zone->get_id() ) ];
|
||||
|
||||
// Execute the request expecting failure.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
// Execute the request expecting success.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'shippingZone',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zone->get_id() ) ),
|
||||
$this->expectedField( 'name', $shipping_zone->get_zone_name() ),
|
||||
$this->expectedField( 'order', $shipping_zone->get_zone_order() ),
|
||||
$this->expectedNode(
|
||||
'locations',
|
||||
[
|
||||
$this->expectedField( 'code', 'US' ),
|
||||
$this->expectedField( 'type', 'COUNTRY' )
|
||||
]
|
||||
),
|
||||
$this->expectedNode(
|
||||
'methods.edges',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone_method', $instance_id ) ),
|
||||
$this->expectedField( 'instanceId', $instance_id ),
|
||||
$this->expectedField( 'order', $shipping_method->method_order ),
|
||||
$this->expectedField( 'enabled', $shipping_method->is_enabled() ),
|
||||
$this->expectedNode(
|
||||
'settings',
|
||||
[
|
||||
$this->expectedField( 'id', 'cost' ),
|
||||
$this->expectedField( 'label', 'Cost' ),
|
||||
$this->expectedField( 'description', self::NOT_FALSY ),
|
||||
$this->expectedField( 'type', 'TEXT' ),
|
||||
$this->expectedField( 'value', '10' ),
|
||||
$this->expectedField( 'default', self::IS_NULL ),
|
||||
$this->expectedField( 'placeholder', self::IS_NULL ),
|
||||
],
|
||||
)
|
||||
],
|
||||
0
|
||||
)
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testShippingZonesQuery() {
|
||||
// Create a shipping zones.
|
||||
$shipping_zones = $this->factory->shipping_zone->create_many( 3 );
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'query {
|
||||
shippingZones {
|
||||
nodes {
|
||||
id
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
/**
|
||||
* Assertion One
|
||||
*
|
||||
* Confirm permission check is working
|
||||
*/
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$this->assertQuerySuccessful( $response, [ $this->expectedField( 'shippingZones.nodes', self::IS_FALSY ) ] );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$expected = [
|
||||
$this->expectedNode(
|
||||
'shippingZones.nodes',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zones[0] ) )
|
||||
]
|
||||
),
|
||||
$this->expectedNode(
|
||||
'shippingZones.nodes',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zones[1] ) )
|
||||
]
|
||||
),
|
||||
$this->expectedNode(
|
||||
'shippingZones.nodes',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'shipping_zone', $shipping_zones[2] ) )
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
class TaxClassMutationsTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
|
||||
public function testCreateTaxClassMutation() {
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: CreateTaxClassInput!) {
|
||||
createTaxClass(input: $input) {
|
||||
taxClass {
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'name' => 'Test Tax Class',
|
||||
'slug' => 'test-tax-class'
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request expecting failure due to missing permissions.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'createTaxClass.taxClass',
|
||||
[
|
||||
$this->expectedField( 'name', 'Test Tax Class' ),
|
||||
$this->expectedField( 'slug', 'test-tax-class' )
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testDeleteTaxClassMutation() {
|
||||
// Create a tax class.
|
||||
$tax_class = $this->factory->tax_class->create();
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: DeleteTaxClassInput!) {
|
||||
deleteTaxClass(input: $input) {
|
||||
taxClass {
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'slug' => $tax_class['slug']
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request expecting failure due to missing permissions.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'deleteTaxClass.taxClass',
|
||||
[
|
||||
$this->expectedField( 'name', $tax_class['name'] ),
|
||||
$this->expectedField( 'slug', $tax_class['slug'] )
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
|
||||
// Ensure the tax class was deleted.
|
||||
$tax_class = $this->factory->tax_class->get_object_by_id( $tax_class['slug'] );
|
||||
$this->assertNull( $tax_class );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
class TaxClassQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
|
||||
public function testTaxClassesQuery() {
|
||||
// Create tax classes.
|
||||
$tax_classes = $this->factory->tax_class->create_many( 2 );
|
||||
|
||||
// Prepare the request.
|
||||
$query = '{
|
||||
taxClasses {
|
||||
nodes {
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Execute the request expecting failure due to missing permissions.
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$this->assertQuerySuccessful( $response, [ $this->expectedField( 'taxClasses.nodes', self::IS_FALSY ) ] );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$expected = [
|
||||
$this->expectedNode(
|
||||
'taxClasses.nodes',
|
||||
[
|
||||
$this->expectedField( 'name', $tax_classes[0]['name'] ),
|
||||
$this->expectedField( 'slug', $tax_classes[0]['slug'] ),
|
||||
]
|
||||
),
|
||||
$this->expectedNode(
|
||||
'taxClasses.nodes',
|
||||
[
|
||||
$this->expectedField( 'name', $tax_classes[1]['name'] ),
|
||||
$this->expectedField( 'slug', $tax_classes[1]['slug'] ),
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
use WPGraphQL\Type\WPEnumType;
|
||||
|
||||
class TaxRateMutationsTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
|
||||
public function testCreateTaxRateMutation() {
|
||||
// Create tax class.
|
||||
$tax_class = $this->factory->tax_class->create();
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: CreateTaxRateInput!) {
|
||||
createTaxRate(input: $input) {
|
||||
taxRate {
|
||||
id
|
||||
rate
|
||||
country
|
||||
state
|
||||
postcode
|
||||
city
|
||||
postcodes
|
||||
cities
|
||||
priority
|
||||
compound
|
||||
shipping
|
||||
order
|
||||
class
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'rate' => '10',
|
||||
'country' => 'US',
|
||||
'state' => 'CA',
|
||||
'postcodes' => [ '12345', '67890' ],
|
||||
'cities' => [ 'Los Angeles', 'San Francisco' ],
|
||||
'priority' => 1,
|
||||
'compound' => false,
|
||||
'shipping' => false,
|
||||
'order' => 0,
|
||||
'class' => WPEnumType::get_safe_name( $tax_class['slug'] )
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request expecting failure due to missing permissions.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'createTaxRate.taxRate',
|
||||
[
|
||||
$this->expectedField( 'id', self::NOT_NULL ),
|
||||
$this->expectedField( 'rate', self::NOT_FALSY ),
|
||||
$this->expectedField( 'country', 'US' ),
|
||||
$this->expectedField( 'state', 'CA' ),
|
||||
$this->expectedField( 'postcode', '67890' ),
|
||||
$this->expectedField( 'postcodes.0', '12345' ),
|
||||
$this->expectedField( 'postcodes.1', '67890' ),
|
||||
$this->expectedField( 'city', 'SAN FRANCISCO' ),
|
||||
$this->expectedField( 'cities.0', 'LOS ANGELES' ),
|
||||
$this->expectedField( 'cities.1', 'SAN FRANCISCO' ),
|
||||
$this->expectedField( 'priority', 1 ),
|
||||
$this->expectedField( 'compound', false ),
|
||||
$this->expectedField( 'shipping', false ),
|
||||
$this->expectedField( 'order', 0 ),
|
||||
$this->expectedField( 'class', WPEnumType::get_safe_name( $tax_class['slug'] ) )
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testUpdateTaxRateMutation() {
|
||||
// Create a tax class.
|
||||
$old_tax_class = $this->factory->tax_class->create();
|
||||
$new_tax_class = $this->factory->tax_class->create();
|
||||
|
||||
// Create a tax rate.
|
||||
$tax_rate_id = $this->factory->tax_rate->create( [ 'class' => $old_tax_class['slug'] ] );
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: UpdateTaxRateInput!) {
|
||||
updateTaxRate(input: $input) {
|
||||
taxRate {
|
||||
id
|
||||
rate
|
||||
country
|
||||
state
|
||||
postcodes
|
||||
cities
|
||||
priority
|
||||
compound
|
||||
shipping
|
||||
order
|
||||
class
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'id' => $tax_rate_id,
|
||||
'rate' => '20',
|
||||
'country' => 'US',
|
||||
'state' => 'NY',
|
||||
'postcodes' => [ '54321', '09876' ],
|
||||
'cities' => [ 'New York', 'Buffalo' ],
|
||||
'priority' => 2,
|
||||
'compound' => true,
|
||||
'shipping' => true,
|
||||
'order' => 1,
|
||||
'class' => WPEnumType::get_safe_name( $new_tax_class['slug'] )
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request expecting failure due to missing permissions.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'updateTaxRate.taxRate',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'tax_rate', $tax_rate_id ) ),
|
||||
$this->expectedField( 'rate', self::NOT_FALSY ),
|
||||
$this->expectedField( 'country', 'US' ),
|
||||
$this->expectedField( 'state', 'NY' ),
|
||||
$this->expectedField( 'postcodes.0', '54321' ),
|
||||
$this->expectedField( 'postcodes.1', '09876' ),
|
||||
$this->expectedField( 'cities.0', 'NEW YORK' ),
|
||||
$this->expectedField( 'cities.1', 'BUFFALO' ),
|
||||
$this->expectedField( 'priority', 2 ),
|
||||
$this->expectedField( 'compound', true ),
|
||||
$this->expectedField( 'shipping', true ),
|
||||
$this->expectedField( 'order', 1 ),
|
||||
$this->expectedField( 'class', WPEnumType::get_safe_name( $new_tax_class['slug'] ) ),
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
}
|
||||
|
||||
public function testDeleteTaxRateMutation() {
|
||||
// Create a tax rate.
|
||||
$tax_rate = $this->factory->tax_rate->create_and_get(
|
||||
[
|
||||
'rate' => '30',
|
||||
'country' => 'US',
|
||||
'state' => 'TX',
|
||||
'class' => 'zero-rate',
|
||||
]
|
||||
);
|
||||
|
||||
// Prepare the request.
|
||||
$query = 'mutation ($input: DeleteTaxRateInput!) {
|
||||
deleteTaxRate(input: $input) {
|
||||
taxRate {
|
||||
id
|
||||
rate
|
||||
country
|
||||
state
|
||||
class
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
// Prepare the variables.
|
||||
$variables = [
|
||||
'input' => [
|
||||
'id' => absint( $tax_rate->tax_rate_id ),
|
||||
]
|
||||
];
|
||||
|
||||
// Execute the request expecting failure due to missing permissions.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
// Execute the request.
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$expected = [
|
||||
$this->expectedObject(
|
||||
'deleteTaxRate.taxRate',
|
||||
[
|
||||
$this->expectedField( 'id', $this->toRelayId( 'tax_rate', $tax_rate->tax_rate_id ) ),
|
||||
$this->expectedField( 'rate', self::NOT_FALSY ),
|
||||
$this->expectedField( 'country', 'US' ),
|
||||
$this->expectedField( 'state', 'TX' ),
|
||||
$this->expectedField( 'class', 'ZERO_RATE' ),
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
// Validate the response.
|
||||
$this->assertQuerySuccessful( $response, $expected );
|
||||
|
||||
// Ensure the tax rate has been deleted.
|
||||
$tax_rate = $this->factory->tax_rate->get_object_by_id( $tax_rate->tax_rate_id );
|
||||
$this->assertNull( $tax_rate );
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@ class TaxRateQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQ
|
||||
$this->expectedField( 'taxRate.databaseId', absint( $rate->tax_rate_id ) ),
|
||||
$this->expectedField( 'taxRate.country', ! empty( $rate->tax_rate_country ) ? $rate->tax_rate_country : self::IS_NULL ),
|
||||
$this->expectedField( 'taxRate.state', ! empty( $rate->tax_rate_state ) ? $rate->tax_rate_state : self::IS_NULL ),
|
||||
$this->expectedField( 'taxRate.postcode', ! empty( $rate->tax_rate_postcode ) ? $rate->tax_rate_postcode : [ '*' ] ),
|
||||
$this->expectedField( 'taxRate.city', ! empty( $rate->tax_rate_city ) ? $rate->tax_rate_city : [ '*' ] ),
|
||||
$this->expectedField( 'taxRate.postcode', ! empty( $rate->tax_rate_postcode ) ? $rate->tax_rate_postcode : '*' ),
|
||||
$this->expectedField( 'taxRate.city', ! empty( $rate->tax_rate_city ) ? $rate->tax_rate_city : '*' ),
|
||||
$this->expectedField( 'taxRate.rate', ! empty( $rate->tax_rate ) ? $rate->tax_rate : self::IS_NULL ),
|
||||
$this->expectedField( 'taxRate.name', ! empty( $rate->tax_rate_name ) ? $rate->tax_rate_name : self::IS_NULL ),
|
||||
$this->expectedField( 'taxRate.priority', absint( $rate->tax_rate_priority ) ),
|
||||
@@ -50,6 +50,14 @@ class TaxRateQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQ
|
||||
}
|
||||
';
|
||||
|
||||
// Execute the request expecting failure due to missing permissions.
|
||||
$variables = [ 'id' => $this->toRelayId( 'tax_rate', $rate ) ];
|
||||
$response = $this->graphql( compact( 'query', 'variables' ) );
|
||||
$this->assertQueryError( $response );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
/**
|
||||
* Assertion One
|
||||
*
|
||||
@@ -119,6 +127,13 @@ class TaxRateQueriesTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQ
|
||||
}
|
||||
';
|
||||
|
||||
// Execute the request expecting failure due to missing permissions.
|
||||
$response = $this->graphql( compact( 'query' ) );
|
||||
$this->assertQuerySuccessful( $response, [ $this->expectedField( 'taxRates.nodes', self::IS_FALSY ) ] );
|
||||
|
||||
// Login as shop manager.
|
||||
$this->loginAsShopManager();
|
||||
|
||||
/**
|
||||
* Assertion One
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user