Skip to content

Commit 628816f

Browse files
authored
feat: CartItem converted to WPInterface type (#798)
1 parent 81502f9 commit 628816f

File tree

4 files changed

+308
-245
lines changed

4 files changed

+308
-245
lines changed

includes/class-type-registry.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public function init() {
7070
Type\WPInterface\Cart_Error::register_interface();
7171
Type\WPInterface\Payment_Token::register_interface();
7272
Type\WPInterface\Product_Union::register_interface();
73+
Type\WPInterface\Cart_Item::register_interface();
7374

7475
/**
7576
* Objects.

includes/class-wp-graphql-woocommerce.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ private function includes() {
244244
require $include_directory_path . 'type/interface/class-product.php';
245245
require $include_directory_path . 'type/interface/class-payment-token.php';
246246
require $include_directory_path . 'type/interface/class-product-union.php';
247+
require $include_directory_path . 'type/interface/class-cart-item.php';
247248

248249
// Include object type class files.
249250
require $include_directory_path . 'type/object/class-cart-error-types.php';
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
<?php
2+
/**
3+
* WPInterface Type - CartItem
4+
*
5+
* @package WPGraphQL\WooCommerce\Type\WPInterface
6+
* @since TBD
7+
*/
8+
9+
namespace WPGraphQL\WooCommerce\Type\WPInterface;
10+
11+
use GraphQL\Error\UserError;
12+
use GraphQL\Type\Definition\ResolveInfo;
13+
use WPGraphQL\AppContext;
14+
use WPGraphQL\Data\Connection\PostObjectConnectionResolver;
15+
use WPGraphQL\WooCommerce\Data\Connection\Variation_Attribute_Connection_Resolver;
16+
17+
/**
18+
* Class Cart_Item
19+
*/
20+
class Cart_Item {
21+
/**
22+
* Registers the "CartItem" interface and "SimpleCartItem" type..
23+
*
24+
* @return void
25+
*/
26+
public static function register_interface() {
27+
// Register cart item interface.
28+
register_graphql_interface_type(
29+
'CartItem',
30+
[
31+
'description' => __( 'Cart item interface.', 'wp-graphql-woocommerce' ),
32+
'interfaces' => [ 'Node' ],
33+
'fields' => self::get_fields(),
34+
'connections' => self::get_connections(),
35+
'resolveType' => static function ( $cart_item ) {
36+
/**
37+
* Instance of the WPGraphQL TypeRegistry.
38+
*
39+
* @var \WPGraphQL\Registry\TypeRegistry $type_registry
40+
*/
41+
$type_registry = \WPGraphQL::get_type_registry();
42+
43+
$type_name = apply_filters( 'woographql_cart_item_type', 'SimpleCartItem', $cart_item );
44+
if ( empty( $type_name ) ) {
45+
throw new UserError( __( 'Invalid cart item type provided.', 'wp-graphql-woocommerce' ) );
46+
}
47+
48+
return $type_registry->get_type( $type_name );
49+
},
50+
]
51+
);
52+
53+
register_graphql_object_type(
54+
'SimpleCartItem',
55+
[
56+
'eagerlyLoadType' => true,
57+
'description' => __( 'A item in the cart', 'wp-graphql-woocommerce' ),
58+
'interfaces' => [ 'Node', 'CartItem' ],
59+
'fields' => [],
60+
]
61+
);
62+
}
63+
64+
/**
65+
* Returns common cart field definitions.
66+
*
67+
* @return array
68+
*/
69+
public static function get_fields() {
70+
return [
71+
'key' => [
72+
'type' => [ 'non_null' => 'ID' ],
73+
'description' => __( 'CartItem ID', 'wp-graphql-woocommerce' ),
74+
'resolve' => static function ( $source ) {
75+
return ! empty( $source['key'] ) ? $source['key'] : null;
76+
},
77+
],
78+
'quantity' => [
79+
'type' => 'Int',
80+
'description' => __( 'Quantity of the product', 'wp-graphql-woocommerce' ),
81+
'resolve' => static function ( $source ) {
82+
return isset( $source['quantity'] ) ? absint( $source['quantity'] ) : null;
83+
},
84+
],
85+
'subtotal' => [
86+
'type' => 'String',
87+
'description' => __( 'Item\'s subtotal', 'wp-graphql-woocommerce' ),
88+
'args' => [
89+
'format' => [
90+
'type' => 'PricingFieldFormatEnum',
91+
'description' => __( 'Format of the price', 'wp-graphql-woocommerce' ),
92+
],
93+
],
94+
'resolve' => static function ( $source, array $args ) {
95+
$price = isset( $source['line_subtotal'] ) ? floatval( $source['line_subtotal'] ) : 0;
96+
97+
if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
98+
return $price;
99+
}
100+
101+
return \wc_graphql_price( $price );
102+
},
103+
],
104+
'subtotalTax' => [
105+
'type' => 'String',
106+
'description' => __( 'Item\'s subtotal tax', 'wp-graphql-woocommerce' ),
107+
'args' => [
108+
'format' => [
109+
'type' => 'PricingFieldFormatEnum',
110+
'description' => __( 'Format of the price', 'wp-graphql-woocommerce' ),
111+
],
112+
],
113+
'resolve' => static function ( $source, array $args ) {
114+
$price = isset( $source['line_subtotal_tax'] ) ? floatval( $source['line_subtotal_tax'] ) : 0;
115+
116+
if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
117+
return $price;
118+
}
119+
120+
return \wc_graphql_price( $price );
121+
},
122+
],
123+
'total' => [
124+
'type' => 'String',
125+
'description' => __( 'Item\'s total', 'wp-graphql-woocommerce' ),
126+
'args' => [
127+
'format' => [
128+
'type' => 'PricingFieldFormatEnum',
129+
'description' => __( 'Format of the price', 'wp-graphql-woocommerce' ),
130+
],
131+
],
132+
'resolve' => static function ( $source, array $args ) {
133+
$price_without_tax = isset( $source['line_total'] ) ? floatval( $source['line_total'] ) : 0;
134+
$tax = isset( $source['line_tax'] ) ? floatval( $source['line_tax'] ) : 0;
135+
$price = $price_without_tax + $tax;
136+
137+
if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
138+
return $price;
139+
}
140+
141+
return \wc_graphql_price( $price );
142+
},
143+
],
144+
'tax' => [
145+
'type' => 'String',
146+
'description' => __( 'Item\'s tax', 'wp-graphql-woocommerce' ),
147+
'args' => [
148+
'format' => [
149+
'type' => 'PricingFieldFormatEnum',
150+
'description' => __( 'Format of the price', 'wp-graphql-woocommerce' ),
151+
],
152+
],
153+
'resolve' => static function ( $source, array $args ) {
154+
$price = isset( $source['line_tax'] ) ? floatval( $source['line_tax'] ) : 0;
155+
156+
if ( isset( $args['format'] ) && 'raw' === $args['format'] ) {
157+
return $price;
158+
}
159+
160+
return \wc_graphql_price( $price );
161+
},
162+
],
163+
'extraData' => [
164+
'type' => [ 'list_of' => 'MetaData' ],
165+
'description' => __( 'Object meta data', 'wp-graphql-woocommerce' ),
166+
'args' => [
167+
'key' => [
168+
'type' => 'String',
169+
'description' => __( 'Retrieve meta by key', 'wp-graphql-woocommerce' ),
170+
],
171+
'keysIn' => [
172+
'type' => [ 'list_of' => 'String' ],
173+
'description' => __( 'Retrieve multiple metas by key', 'wp-graphql-woocommerce' ),
174+
],
175+
],
176+
'resolve' => static function ( $source, array $args ) {
177+
// Check if "key" argument set and assigns to target "keys" array.
178+
if ( ! empty( $args['key'] ) && ! empty( $source[ $args['key'] ] ) ) {
179+
$keys = [ $args['key'] ];
180+
} elseif ( ! empty( $args['keysIn'] ) ) {
181+
// Check if "keysIn" argument set and assigns to target "keys" array.
182+
$keys = [];
183+
foreach ( $args['keysIn'] as $key ) {
184+
if ( ! empty( $source[ $key ] ) ) {
185+
$keys[] = $key;
186+
}
187+
}
188+
} else {
189+
// If no arguments set, all extra data keys are assigns to target "keys" array.
190+
$keys = array_diff(
191+
array_keys( $source ),
192+
[
193+
'key',
194+
'product_id',
195+
'variation_id',
196+
'variation',
197+
'quantity',
198+
'data',
199+
'data_hash',
200+
'line_tax_data',
201+
'line_subtotal',
202+
'line_subtotal_tax',
203+
'line_total',
204+
'line_tax',
205+
]
206+
);
207+
}//end if
208+
// Create meta ID prefix.
209+
$id_prefix = apply_filters( 'graphql_woocommerce_cart_meta_id_prefix', 'cart_' );
210+
211+
// Format meta data for resolution.
212+
$data = [];
213+
foreach ( $keys as $key ) {
214+
$data[] = (object) [
215+
'id' => "{$id_prefix}_{$key}",
216+
'key' => $key,
217+
'value' => is_array( $source[ $key ] ) ? wp_json_encode( $source[ $key ] ) : $source[ $key ],
218+
];
219+
}
220+
221+
return $data;
222+
},
223+
],
224+
];
225+
}
226+
227+
/**
228+
* Defines connections.
229+
*
230+
* @return array
231+
*/
232+
public static function get_connections() {
233+
return [
234+
'product' => [
235+
'toType' => 'Product',
236+
'oneToOne' => true,
237+
'edgeFields' => [
238+
'simpleVariations' => [
239+
'type' => [ 'list_of' => 'SimpleAttribute' ],
240+
'description' => __( 'Simple variation attribute data', 'wp-graphql-woocommerce' ),
241+
'resolve' => static function ( $source ) {
242+
$attributes = [];
243+
244+
$variation = $source['node'];
245+
$cart_item_data = $source['source'];
246+
$simple_attribute_data = $cart_item_data['variation'];
247+
foreach ( $simple_attribute_data as $name => $value ) {
248+
$attributes[] = compact( 'name', 'value' );
249+
}
250+
251+
return $attributes;
252+
},
253+
],
254+
],
255+
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
256+
$id = $source['product_id'];
257+
$resolver = new PostObjectConnectionResolver( $source, $args, $context, $info, 'product' );
258+
259+
return $resolver
260+
->one_to_one()
261+
->set_query_arg( 'p', $id )
262+
->get_connection();
263+
},
264+
],
265+
'variation' => [
266+
'toType' => 'ProductVariation',
267+
'oneToOne' => true,
268+
'edgeFields' => [
269+
'attributes' => [
270+
'type' => [ 'list_of' => 'VariationAttribute' ],
271+
'description' => __( 'Attributes of the variation.', 'wp-graphql-woocommerce' ),
272+
'resolve' => static function ( $source ) {
273+
$attributes = [];
274+
275+
$variation = $source['node'];
276+
$cart_item_data = $source['source'];
277+
$cart_variation_data = $cart_item_data['variation'];
278+
foreach ( $variation->attributes as $name => $default_value ) {
279+
if ( isset( $cart_variation_data[ "attribute_{$name}" ] ) ) {
280+
$attributes[ $name ] = $cart_variation_data[ "attribute_{$name}" ];
281+
} else {
282+
$attributes[ $name ] = $default_value;
283+
}
284+
}
285+
286+
return Variation_Attribute_Connection_Resolver::variation_attributes_to_data_array( $attributes, $variation->ID );
287+
},
288+
],
289+
],
290+
'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) {
291+
$id = ! empty( $source['variation_id'] ) ? $source['variation_id'] : null;
292+
$resolver = new PostObjectConnectionResolver( $source, $args, $context, $info, 'product_variation' );
293+
294+
if ( ! $id ) {
295+
return null;
296+
}
297+
298+
return $resolver
299+
->one_to_one()
300+
->set_query_arg( 'p', $id )
301+
->get_connection();
302+
},
303+
],
304+
];
305+
}
306+
}

0 commit comments

Comments
 (0)