Skip to content
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
1 change: 1 addition & 0 deletions includes/class-type-registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public function init() {
Type\WPInterface\Cart_Error::register_interface();
Type\WPInterface\Payment_Token::register_interface();
Type\WPInterface\Product_Union::register_interface();
Type\WPInterface\Cart_Item::register_interface();

/**
* Objects.
Expand Down
1 change: 1 addition & 0 deletions includes/class-wp-graphql-woocommerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ private function includes() {
require $include_directory_path . 'type/interface/class-product.php';
require $include_directory_path . 'type/interface/class-payment-token.php';
require $include_directory_path . 'type/interface/class-product-union.php';
require $include_directory_path . 'type/interface/class-cart-item.php';

// Include object type class files.
require $include_directory_path . 'type/object/class-cart-error-types.php';
Expand Down
306 changes: 306 additions & 0 deletions includes/type/interface/class-cart-item.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
<?php
/**
* WPInterface Type - CartItem
*
* @package WPGraphQL\WooCommerce\Type\WPInterface
* @since TBD
*/

namespace WPGraphQL\WooCommerce\Type\WPInterface;

use GraphQL\Error\UserError;
use GraphQL\Type\Definition\ResolveInfo;
use WPGraphQL\AppContext;
use WPGraphQL\Data\Connection\PostObjectConnectionResolver;
use WPGraphQL\WooCommerce\Data\Connection\Variation_Attribute_Connection_Resolver;

/**
* Class Cart_Item
*/
class Cart_Item {
/**
* Registers the "CartItem" interface and "SimpleCartItem" type..
*
* @return void
*/
public static function register_interface() {
// Register cart item interface.
register_graphql_interface_type(
'CartItem',
[
'description' => __( 'Cart item interface.', 'wp-graphql-woocommerce' ),
'interfaces' => [ 'Node' ],
'fields' => self::get_fields(),
'connections' => self::get_connections(),
'resolveType' => static function ( $cart_item ) {
/**
* Instance of the WPGraphQL TypeRegistry.
*
* @var \WPGraphQL\Registry\TypeRegistry $type_registry
*/
$type_registry = \WPGraphQL::get_type_registry();

$type_name = apply_filters( 'woographql_cart_item_type', 'SimpleCartItem', $cart_item );
if ( empty( $type_name ) ) {
throw new UserError( __( 'Invalid cart item type provided.', 'wp-graphql-woocommerce' ) );
}

return $type_registry->get_type( $type_name );
},
]
);

register_graphql_object_type(
'SimpleCartItem',
[
'eagerlyLoadType' => true,
'description' => __( 'A item in the cart', 'wp-graphql-woocommerce' ),
'interfaces' => [ 'Node', 'CartItem' ],
'fields' => [],
]
);
}

/**
* Returns common cart field definitions.
*
* @return array
*/
public static function get_fields() {
return [
'key' => [
'type' => [ 'non_null' => 'ID' ],
'description' => __( 'CartItem ID', 'wp-graphql-woocommerce' ),
'resolve' => static function ( $source ) {
return ! empty( $source['key'] ) ? $source['key'] : null;
},
],
'quantity' => [
'type' => 'Int',
'description' => __( 'Quantity of the product', 'wp-graphql-woocommerce' ),
'resolve' => static function ( $source ) {
return isset( $source['quantity'] ) ? absint( $source['quantity'] ) : null;
},
],
'subtotal' => [
'type' => 'String',
'description' => __( 'Item\'s subtotal', 'wp-graphql-woocommerce' ),
'args' => [
'format' => [
'type' => 'PricingFieldFormatEnum',
'description' => __( 'Format of the price', 'wp-graphql-woocommerce' ),
],
],
'resolve' => static function ( $source, array $args ) {
$price = isset( $source['line_subtotal'] ) ? floatval( $source['line_subtotal'] ) : 0;

if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
return $price;
}

return \wc_graphql_price( $price );
},
],
'subtotalTax' => [
'type' => 'String',
'description' => __( 'Item\'s subtotal tax', 'wp-graphql-woocommerce' ),
'args' => [
'format' => [
'type' => 'PricingFieldFormatEnum',
'description' => __( 'Format of the price', 'wp-graphql-woocommerce' ),
],
],
'resolve' => static function ( $source, array $args ) {
$price = isset( $source['line_subtotal_tax'] ) ? floatval( $source['line_subtotal_tax'] ) : 0;

if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
return $price;
}

return \wc_graphql_price( $price );
},
],
'total' => [
'type' => 'String',
'description' => __( 'Item\'s total', 'wp-graphql-woocommerce' ),
'args' => [
'format' => [
'type' => 'PricingFieldFormatEnum',
'description' => __( 'Format of the price', 'wp-graphql-woocommerce' ),
],
],
'resolve' => static function ( $source, array $args ) {
$price_without_tax = isset( $source['line_total'] ) ? floatval( $source['line_total'] ) : 0;
$tax = isset( $source['line_tax'] ) ? floatval( $source['line_tax'] ) : 0;
$price = $price_without_tax + $tax;

if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
return $price;
}

return \wc_graphql_price( $price );
},
],
'tax' => [
'type' => 'String',
'description' => __( 'Item\'s tax', 'wp-graphql-woocommerce' ),
'args' => [
'format' => [
'type' => 'PricingFieldFormatEnum',
'description' => __( 'Format of the price', 'wp-graphql-woocommerce' ),
],
],
'resolve' => static function ( $source, array $args ) {
$price = isset( $source['line_tax'] ) ? floatval( $source['line_tax'] ) : 0;

if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
return $price;
}

return \wc_graphql_price( $price );
},
],
'extraData' => [
'type' => [ 'list_of' => 'MetaData' ],
'description' => __( 'Object meta data', 'wp-graphql-woocommerce' ),
'args' => [
'key' => [
'type' => 'String',
'description' => __( 'Retrieve meta by key', 'wp-graphql-woocommerce' ),
],
'keysIn' => [
'type' => [ 'list_of' => 'String' ],
'description' => __( 'Retrieve multiple metas by key', 'wp-graphql-woocommerce' ),
],
],
'resolve' => static function ( $source, array $args ) {
// Check if "key" argument set and assigns to target "keys" array.
if ( ! empty( $args['key'] ) && ! empty( $source[ $args['key'] ] ) ) {
$keys = [ $args['key'] ];
} elseif ( ! empty( $args['keysIn'] ) ) {
// Check if "keysIn" argument set and assigns to target "keys" array.
$keys = [];
foreach ( $args['keysIn'] as $key ) {
if ( ! empty( $source[ $key ] ) ) {
$keys[] = $key;
}
}
} else {
// If no arguments set, all extra data keys are assigns to target "keys" array.
$keys = array_diff(
array_keys( $source ),
[
'key',
'product_id',
'variation_id',
'variation',
'quantity',
'data',
'data_hash',
'line_tax_data',
'line_subtotal',
'line_subtotal_tax',
'line_total',
'line_tax',
]
);
}//end if
// Create meta ID prefix.
$id_prefix = apply_filters( 'graphql_woocommerce_cart_meta_id_prefix', 'cart_' );

// Format meta data for resolution.
$data = [];
foreach ( $keys as $key ) {
$data[] = (object) [
'id' => "{$id_prefix}_{$key}",
'key' => $key,
'value' => is_array( $source[ $key ] ) ? wp_json_encode( $source[ $key ] ) : $source[ $key ],
];
}

return $data;
},
],
];
}

/**
* Defines connections.
*
* @return array
*/
public static function get_connections() {
return [
'product' => [
'toType' => 'Product',
'oneToOne' => true,
'edgeFields' => [
'simpleVariations' => [
'type' => [ 'list_of' => 'SimpleAttribute' ],
'description' => __( 'Simple variation attribute data', 'wp-graphql-woocommerce' ),
'resolve' => static function ( $source ) {
$attributes = [];

$variation = $source['node'];
$cart_item_data = $source['source'];
$simple_attribute_data = $cart_item_data['variation'];
foreach ( $simple_attribute_data as $name => $value ) {
$attributes[] = compact( 'name', 'value' );
}

return $attributes;
},
],
],
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
$id = $source['product_id'];
$resolver = new PostObjectConnectionResolver( $source, $args, $context, $info, 'product' );

return $resolver
->one_to_one()
->set_query_arg( 'p', $id )
->get_connection();
},
],
'variation' => [
'toType' => 'ProductVariation',
'oneToOne' => true,
'edgeFields' => [
'attributes' => [
'type' => [ 'list_of' => 'VariationAttribute' ],
'description' => __( 'Attributes of the variation.', 'wp-graphql-woocommerce' ),
'resolve' => static function ( $source ) {
$attributes = [];

$variation = $source['node'];
$cart_item_data = $source['source'];
$cart_variation_data = $cart_item_data['variation'];
foreach ( $variation->attributes as $name => $default_value ) {
if ( isset( $cart_variation_data[ "attribute_{$name}" ] ) ) {
$attributes[ $name ] = $cart_variation_data[ "attribute_{$name}" ];
} else {
$attributes[ $name ] = $default_value;
}
}

return Variation_Attribute_Connection_Resolver::variation_attributes_to_data_array( $attributes, $variation->ID );
},
],
],
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
$id = ! empty( $source['variation_id'] ) ? $source['variation_id'] : null;
$resolver = new PostObjectConnectionResolver( $source, $args, $context, $info, 'product_variation' );

if ( ! $id ) {
return null;
}

return $resolver
->one_to_one()
->set_query_arg( 'p', $id )
->get_connection();
},
],
];
}
}
Loading