Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updateItemQuantities mutation #106

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions includes/class-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Meta_Data_Input;
use WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Shipping_Line_Input;
use WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Create_Account_Input;
use WPGraphQL\Extensions\WooCommerce\Type\WPInputObject\Cart_Item_Quantity_Input;
use WPGraphQL\Extensions\WooCommerce\Type\WPObject\Coupon_Type;
use WPGraphQL\Extensions\WooCommerce\Type\WPObject\Order_Type;
use WPGraphQL\Extensions\WooCommerce\Type\WPObject\Order_Item_Type;
Expand Down Expand Up @@ -67,7 +68,7 @@
use WPGraphQL\Extensions\WooCommerce\Mutation\Customer_Register;
use WPGraphQL\Extensions\WooCommerce\Mutation\Customer_Update;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Add_Item;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Update_Item_Quantity;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Update_Item_Quantities;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Remove_Items;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Restore_Items;
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Empty;
Expand Down Expand Up @@ -128,6 +129,7 @@ public static function graphql_register_types() {
Meta_Data_Input::register();
Shipping_Line_Input::register();
Create_Account_Input::register();
Cart_Item_Quantity_Input::register();

// Objects.
Coupon_Type::register();
Expand Down Expand Up @@ -167,7 +169,7 @@ public static function graphql_register_types() {
Customer_Register::register_mutation();
Customer_Update::register_mutation();
Cart_Add_Item::register_mutation();
Cart_Update_Item_Quantity::register_mutation();
Cart_Update_Item_Quantities::register_mutation();
Cart_Remove_Items::register_mutation();
Cart_Restore_Items::register_mutation();
Cart_Empty::register_mutation();
Expand Down
17 changes: 17 additions & 0 deletions includes/data/mutation/class-cart-mutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,21 @@ public static function prepare_cart_fee( $input, $context, $info ) {

return apply_filters( 'woocommerce_new_cart_fee_data', $cart_item_args, $input, $context, $info );
}

/**
* Validate CartItemQuantityInput item.
*
* @param array $item CartItemQuantityInput object.
*
* @return boolean
*/
public static function item_is_valid( array $item ) {
if ( empty( $item['key'] ) ) {
return false;
}
if ( ! isset( $item['quantity'] ) || ! is_numeric( $item['quantity'] ) ) {
return false;
}
return true;
}
}
167 changes: 167 additions & 0 deletions includes/mutation/class-cart-update-item-quantities.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?php
/**
* Mutation - updateItemQuantities
*
* Registers mutation for updating cart item quantities.
*
* @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_Update_Item_Quantities
*/
class Cart_Update_Item_Quantities {
/**
* Registers mutation
*/
public static function register_mutation() {
register_graphql_mutation(
'updateItemQuantities',
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() {
return array(
'items' => array(
'type' => array( 'list_of' => 'CartItemQuantityInput' ),
'description' => __( 'Cart item being updated', 'wp-graphql-woocommerce' ),
),
);
}

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

return $items;
},
),
'removed' => array(
'type' => array( 'list_of' => 'CartItem' ),
'resolve' => function ( $payload ) {
return $payload['removed'];
},
),
'items' => array(
'type' => array( 'list_of' => 'CartItem' ),
'resolve' => function ( $payload ) {
$updated = array();
foreach ( $payload['updated'] as $key ) {
$updated[] = \WC()->cart->get_cart_item( $key );
}

return array_merge( $updated, $payload['removed'] );
},
),
);
}

/**
* Defines the mutation data modification closure.
*
* @return callable
*/
public static function mutate_and_get_payload() {
return function( $input, AppContext $context, ResolveInfo $info ) {
// Confirm "items" exists.
if ( empty( $input['items'] ) ) {
throw new UserError( __( 'No item data provided', 'wp-graphql-woocommerce' ) );
}

// Confirm "items" is value.
if ( ! is_array( $input['items'] ) ) {
throw new UserError( __( 'Provided "items" invalid', 'wp-graphql-woocommerce' ) );
}

do_action( 'woocommerce_graphql_before_set_item_quantities', $input['items'], $input, $context, $info );

// Update quantities. If quantity set to 0, the items in removed.
$removed = array();
$updated = array();
$removed_items = array();
foreach ( $input['items'] as $item ) {
if ( Cart_Mutation::item_is_valid( $item ) ) {
$key = $item['key'];
$quantity = $item['quantity'];
if ( 0 === $quantity ) {
$removed_item = \WC()->cart->get_cart_item( $key );
$removed_items[] = $removed_item;
do_action( 'woocommerce_graphql_before_remove_item', $removed_item, 'update_quantity', $input, $context, $info );
$removed[ $key ] = \WC()->cart->remove_cart_item( $key );
do_action( 'woocommerce_graphql_after_remove_item', $removed_item, 'update_quantity', $input, $context, $info );
continue;
}
do_action( 'woocommerce_graphql_before_set_item_quantity', \WC()->cart->get_cart_item( $key ), $input, $context, $info );
$updated[ $key ] = \WC()->cart->set_quantity( $key, $quantity, true );
do_action( 'woocommerce_graphql_after_set_item_quantity', \WC()->cart->get_cart_item( $key ), $input, $context, $info );
}
}

// Throw failed.
try {
$errors = array_keys(
array_filter(
array_merge( $removed, $updated ),
function( $value ) {
return ! $value;
}
)
);
if ( 0 < count( $errors ) ) {
throw new \Exception(
sprintf(
/* translators: %s: Cart item keys */
__( 'Cart items identified with keys %s failed to update', 'wp-graphql-woocommerce' ),
implode( ', ', $errors )
)
);
}
} catch ( \Exception $e ) {
throw new UserError( $e->getMessage() );
}

do_action(
'woocommerce_graphql_before_set_item_quantities',
array_keys( $updated ),
array_keys( $removed ),
$input,
$context,
$info
);

return array(
'removed' => $removed_items,
'updated' => array_keys( $updated ),
);
};
}
}
93 changes: 0 additions & 93 deletions includes/mutation/class-cart-update-item-quantity.php

This file was deleted.

36 changes: 36 additions & 0 deletions includes/type/input/class-cart-item-quantity-input.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* WPInputObjectType - CartItemQuantityInput
*
* @package \WPGraphQL\Extensions\WooCommerce\Type\WPInputObject
* @since 0.2.0
*/

namespace WPGraphQL\Extensions\WooCommerce\Type\WPInputObject;

/**
* Class Cart_Item_Quantity_Input
*/
class Cart_Item_Quantity_Input {
/**
* Registers type
*/
public static function register() {
register_graphql_input_type(
'CartItemQuantityInput',
array(
'description' => __( 'Cart item quantity', 'wp-graphql-woocommerce' ),
'fields' => array(
'key' => array(
'type' => array( 'non_null' => 'ID' ),
'description' => __( 'Cart item being updated', 'wp-graphql-woocommerce' ),
),
'quantity' => array(
'type' => array( 'non_null' => 'Int' ),
'description' => __( 'Cart item\'s new quantity', 'wp-graphql-woocommerce' ),
),
),
)
);
}
}
Loading