Skip to content

Commit

Permalink
Merge f4b53a5 into a3392c6
Browse files Browse the repository at this point in the history
  • Loading branch information
kidunot89 committed May 7, 2019
2 parents a3392c6 + f4b53a5 commit b987135
Show file tree
Hide file tree
Showing 22 changed files with 1,510 additions and 19 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -12,6 +12,7 @@ branches:
only:
- master
- develop
- release-v0.1.0

cache:
apt: true
Expand Down
17 changes: 16 additions & 1 deletion src/class-actions.php
Expand Up @@ -22,7 +22,7 @@
use WPGraphQL\Extensions\WooCommerce\Type\WPEnum\Tax_Status;
use WPGraphQL\Extensions\WooCommerce\Type\WPEnum\WC_Connection_Orderby_Enum;
use WPGraphQL\Extensions\WooCommerce\Type\WPEnum\Tax_Rate_Connection_Orderby_Enum;
use WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Customer_Connection_Orderby_Input;
use WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Product_Attribute_Input;
use WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\WC_Connection_Orderby_Input;
use WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Tax_Rate_Connection_Orderby_Input;
use WPGraphQL\Extensions\WooCommerce\Type\WPObject\Coupon_Type;
Expand Down Expand Up @@ -54,6 +54,12 @@
use WPGraphQL\Extensions\WooCommerce\Connection\Tax_Rates;
use WPGraphQL\Extensions\WooCommerce\Connection\Shipping_Methods;
use WPGraphQL\Extensions\WooCommerce\Connection\Cart_Items;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Add_Item;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Remove_Item;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Restore_Item;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Empty;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Apply_Coupon;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Remove_Coupon;

/**
* Class Actions
Expand Down Expand Up @@ -92,6 +98,7 @@ public static function graphql_register_types() {
Tax_Rate_Connection_Orderby_Enum::register();

// InputObjects.
Product_Attribute_Input::register();
WC_Connection_Orderby_Input::register();
Tax_Rate_Connection_Orderby_Input::register();

Expand Down Expand Up @@ -126,5 +133,13 @@ public static function graphql_register_types() {
Tax_Rates::register_connections();
Shipping_Methods::register_connections();
Cart_Items::register_connections();

// Mutations.
Cart_Add_Item::register_mutation();
Cart_Remove_Item::register_mutation();
Cart_Restore_Item::register_mutation();
Cart_Empty::register_mutation();
Cart_Apply_Coupon::register_mutation();
Cart_Remove_Coupon::register_mutation();
}
}
30 changes: 30 additions & 0 deletions src/data/class-factory.php
Expand Up @@ -165,6 +165,36 @@ public static function resolve_shipping_method( $id ) {
return new Shipping_Method( $method );
}

/**
* Resolves a cart item by key.
*
* @param string $id cart item key.
*
* @return object
*/
public static function resolve_cart_item( $id ) {
$item = WC()->cart->get_cart_item( $id );

return $item;
}

/**
* Resolves a fee object by ID.
*
* @param int $id Fee object generated ID.
*
* @return object
*/
public static function resolve_cart_fee( $id ) {
$fees = WC()->cart->get_fees();

if ( ! empty( $fees[ $id ] ) ) {
return $fees[ $id ];
}

return null;
}

/**
* Resolves Coupon connections
*
Expand Down
3 changes: 2 additions & 1 deletion src/data/connection/class-coupon-connection-resolver.php
Expand Up @@ -59,6 +59,7 @@ public function __construct( $source, $args, $context, $info ) {
public function should_execute() {
$post_type_obj = get_post_type_object( 'shop_coupon' );
switch ( true ) {
case 'appliedCoupons' === $this->info->fieldName:
case current_user_can( $post_type_obj->cap->edit_posts ):
return true;
default:
Expand Down Expand Up @@ -132,7 +133,7 @@ public function get_query_args() {
foreach ( $this->source->get_applied_coupons() as $code ) {
$ids[] = \wc_get_coupon_id_by_code( $code );
}
$query_args['post__in'] = $ids;
$query_args['post__in'] = ! empty( $ids ) ? $ids : array( '0' );
break;
}
}
Expand Down
35 changes: 35 additions & 0 deletions src/data/mutation/class-cart-mutation.php
@@ -0,0 +1,35 @@
<?php
/**
* Defines helper functions for executing mutations related to the cart.
*
* @package WPGraphQL\Extensions\WooCommerce\Data\Mutation
* @since 0.1.0
*/

namespace WPGraphQL\Extensions\WooCommerce\Data\Mutation;

/**
* Class - Cart_Mutation
*/
class Cart_Mutation {
/**
* Return array of data to be when defining a cart item
*
* @param array $input input data describing cart item.
* @param AppContext $context AppContext instance.
* @param ResolveInfo $info query info.
*
* @return array
*/
public static function prepare_cart_item( $input, $context, $info ) {
$cart_item_args = array(
$input['productId'],
! empty( $input['quantity'] ) ? $input['quantity'] : 1,
! empty( $input['variationId'] ) ? $input['variationId'] : 0,
! empty( $input['variation'] ) ? $input['variation'] : array(),
! empty( $input['extraData'] ) ? json_decode( $input['extraData'], true ) : array(),
);

return apply_filters( 'woocommerce_new_cart_item_data', $cart_item_args, $input, $context, $info );
}
}
Empty file added src/data/mutation/dummy
Empty file.
112 changes: 112 additions & 0 deletions src/mutation/class-cart-add-item.php
@@ -0,0 +1,112 @@
<?php
/**
* Mutation - addToCart
*
* Registers mutation for adding a cart item to the cart.
*
* @package WPGraphQL\Extensions\WooCommerce\Mutation
* @since 0.1.0
*/

namespace WPGraphQL\Extensions\WooCommerce\Mutation;

use GraphQL\Error\UserError;
use GraphQL\Type\Definition\ResolveInfo;
use WPGraphQL\AppContext;
use WPGraphQL\Extensions\WooCommerce\Data\Mutation\Cart_Mutation;

/**
* Class - Cart_Add_Item
*/
class Cart_Add_Item {
/**
* Registers mutation
*/
public static function register_mutation() {
register_graphql_mutation(
'addToCart',
array(
'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() {
$input_fields = array(
'productId' => array(
'type' => array( 'non_null' => 'Int' ),
'description' => __( 'Cart item product database ID or global ID', 'wp-graphql-woocommerce' ),
),
'quantity' => array(
'type' => 'Int',
'description' => __( 'Cart item quantity', 'wp-graphql-woocommerce' ),
),
'variationId' => array(
'type' => 'Int',
'description' => __( 'Cart item product variation database ID or global ID', 'wp-graphql-woocommerce' ),
),
'variation' => array(
'type' => array( 'list_of' => 'ProductAttributeInput' ),
'description' => __( 'Cart item product variation attributes', 'wp-graphql-woocommerce' ),
),
'extraData' => array(
'type' => 'String',
'description' => __( 'JSON string representation of extra cart item data', 'wp-graphql-woocommerce' ),
),
);

return $input_fields;
}

/**
* Defines the mutation output field configuration
*
* @return array
*/
public static function get_output_fields() {
return array(
'cartItem' => array(
'type' => 'CartItem',
'resolve' => function ( $payload ) {
$cart = WC()->cart;
$item = $cart->get_cart_item( $payload['key'] );

return $item;
},
),
);
}

/**
* Defines the mutation data modification closure.
*
* @return callable
*/
public static function mutate_and_get_payload() {
return function( $input, AppContext $context, ResolveInfo $info ) {
// Retrieve product database ID if relay ID provided.
if ( empty( $input['productId'] ) ) {
throw new UserError( __( 'No product ID provided', 'wp-graphql-woocommerce' ) );
}

// Prepare args for "add_to_cart" from input data.
$cart_item_args = Cart_Mutation::prepare_cart_item( $input, $context, $info );

// Get WC_Cart instance.
$cart = WC()->cart;

// Add item to cart and get item key.
$cart_item_key = $cart->add_to_cart( ...$cart_item_args );

// Return payload.
return array( 'key' => $cart_item_key );
};
}
}
107 changes: 107 additions & 0 deletions src/mutation/class-cart-apply-coupon.php
@@ -0,0 +1,107 @@
<?php
/**
* Mutation - applyCoupon
*
* Registers mutation for applying a coupon.
*
* @package WPGraphQL\Extensions\WooCommerce\Mutation
* @since 0.1.0
*/

namespace WPGraphQL\Extensions\WooCommerce\Mutation;

use GraphQL\Error\UserError;
use GraphQL\Type\Definition\ResolveInfo;
use WPGraphQL\AppContext;

/**
* Class - Cart_Apply_Coupon
*/
class Cart_Apply_Coupon {
/**
* Registers mutation
*/
public static function register_mutation() {
register_graphql_mutation(
'applyCoupon',
array(
'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() {
$input_fields = array(
'code' => array(
'type' => array( 'non_null' => 'String' ),
'description' => __( 'Code of coupon being applied', 'wp-graphql-woocommerce' ),
),
);

return $input_fields;
}

/**
* Defines the mutation output field configuration
*
* @return array
*/
public static function get_output_fields() {
return array(
'cart' => array(
'type' => 'Cart',
'resolve' => function ( $payload ) {
return $payload['cart'];
},
),
);
}

/**
* Defines the mutation data modification closure.
*
* @return callable
*/
public static function mutate_and_get_payload() {
return function( $input, AppContext $context, ResolveInfo $info ) {
// Retrieve product database ID if relay ID provided.
if ( empty( $input['code'] ) ) {
throw new UserError( __( 'No coupon code provided', 'wp-graphql-woocommerce' ) );
}

// Get the coupon.
$the_coupon = new \WC_Coupon( $input['code'] );

// Prevent adding coupons by post ID.
if ( $the_coupon->get_code() !== $input['code'] ) {
throw new UserError( __( 'No coupon found with the code provided', 'wp-graphql-woocommerce' ) );
}

// Check it can be used with cart.
if ( ! $the_coupon->is_valid() ) {
throw new UserError( $the_coupon->get_error_message() );
}

// Check if applied.
if ( \WC()->cart->has_discount( $input['code'] ) ) {
throw new UserError( __( 'This coupon has already been applied to the cart', 'wp-graphql-woocommerce' ) );
}

// Get cart item for payload.
$success = \WC()->cart->apply_coupon( $input['code'] );
if ( false === $success ) {
throw new UserError( __( 'Failed to apply coupon. Check for an individual-use coupon on cart.', 'wp-graphql-woocommerce' ) );
}

// Return payload.
return array( 'cart' => \WC()->cart );
};
}
}

0 comments on commit b987135

Please sign in to comment.