mirror of
https://github.com/wp-graphql/wp-graphql-woocommerce.git
synced 2026-08-14 12:53:44 +02:00
fix: General improvements and bugfixes (#899)
This commit is contained in:
Generated
+7
-7
@@ -1129,20 +1129,20 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php73",
|
||||
"version": "v1.30.0",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php73.git",
|
||||
"reference": "ec444d3f3f6505bb28d11afa41e75faadebc10a1"
|
||||
"reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/ec444d3f3f6505bb28d11afa41e75faadebc10a1",
|
||||
"reference": "ec444d3f3f6505bb28d11afa41e75faadebc10a1",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb",
|
||||
"reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
@@ -1185,7 +1185,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php73/tree/v1.30.0"
|
||||
"source": "https://github.com/symfony/polyfill-php73/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1201,7 +1201,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-31T15:07:36+00:00"
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "szepeviktor/phpstan-wordpress",
|
||||
|
||||
@@ -157,7 +157,14 @@ class WooCommerce_Filters {
|
||||
* @return array
|
||||
*/
|
||||
public static function woographql_stripe_gateway_args( $gateway_args, $payment_method ) {
|
||||
if ( 'stripe' === $payment_method ) {
|
||||
/** @var false|\WC_Order|\WC_Order_Refund $order */
|
||||
$order = wc_get_order( $gateway_args[0] );
|
||||
if ( false === $order ) {
|
||||
return $gateway_args;
|
||||
}
|
||||
|
||||
$stripe_source_id = $order->get_meta( '_stripe_source_id' );
|
||||
if ( 'stripe' === $payment_method && ! empty( $stripe_source_id ) ) {
|
||||
$gateway_args = [
|
||||
$gateway_args[0],
|
||||
true,
|
||||
|
||||
@@ -493,6 +493,7 @@ class Checkout_Mutation {
|
||||
if ( WC()->cart->needs_payment() ) {
|
||||
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
|
||||
|
||||
\codecept_debug( $available_gateways );
|
||||
if ( ! isset( $available_gateways[ $data['payment_method'] ] ) ) {
|
||||
throw new UserError( __( 'Invalid payment method.', 'wp-graphql-woocommerce' ) );
|
||||
} else {
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace WPGraphQL\WooCommerce\Data\Mutation;
|
||||
|
||||
use GraphQL\Error\UserError;
|
||||
|
||||
|
||||
/**
|
||||
* Class - Order_Mutation
|
||||
*/
|
||||
@@ -86,8 +87,8 @@ class Order_Mutation {
|
||||
/**
|
||||
* Action called before order is created.
|
||||
*
|
||||
* @param array $input Input data describing order.
|
||||
* @param \WPGraphQL\AppContext $context Request AppContext instance.
|
||||
* @param array $input Input data describing order.
|
||||
* @param \WPGraphQL\AppContext $context Request AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info Request ResolveInfo instance.
|
||||
*/
|
||||
do_action( 'graphql_woocommerce_before_order_create', $input, $context, $info );
|
||||
@@ -118,77 +119,185 @@ class Order_Mutation {
|
||||
* @param \WPGraphQL\AppContext $context AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info ResolveInfo instance.
|
||||
*
|
||||
* @throws \Exception Failed to retrieve order.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function add_items( $input, $order_id, $context, $info ) {
|
||||
/** @var \WC_Order|false $order */
|
||||
$order = \WC_Order_Factory::get_order( $order_id );
|
||||
if ( false === $order ) {
|
||||
throw new \Exception( __( 'Failed to retrieve order.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
$item_group_keys = [
|
||||
'lineItems' => 'line_item',
|
||||
'shippingLines' => 'shipping',
|
||||
'feeLines' => 'fee',
|
||||
];
|
||||
|
||||
$item_groups = [];
|
||||
foreach ( $input as $key => $items ) {
|
||||
$order_items = [];
|
||||
foreach ( $input as $key => $group_items ) {
|
||||
if ( array_key_exists( $key, $item_group_keys ) ) {
|
||||
$type = $item_group_keys[ $key ];
|
||||
$type = $item_group_keys[ $key ];
|
||||
$order_items[ $type ] = [];
|
||||
|
||||
/**
|
||||
* Action called before an item group is added to an order.
|
||||
*
|
||||
* @param array $items Item data being added.
|
||||
* @param integer $order_id ID of target order.
|
||||
* @param \WPGraphQL\AppContext $context Request AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info Request ResolveInfo instance.
|
||||
* @param array $group_items Items data being added.
|
||||
* @param \WC_Order $order Order object.
|
||||
* @param \WPGraphQL\AppContext $context Request AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info Request ResolveInfo instance.
|
||||
*/
|
||||
do_action( "graphql_woocommerce_before_{$type}s_added_to_order", $items, $order_id, $context, $info );
|
||||
do_action( "graphql_woocommerce_before_{$type}s_added_to_order", $group_items, $order, $context, $info );
|
||||
|
||||
foreach ( $items as $item_data ) {
|
||||
// Create Order item.
|
||||
$item_id = ( ! empty( $item_data['id'] ) && \WC_Order_Factory::get_order_item( $item_data['id'] ) )
|
||||
? $item_data['id']
|
||||
: \wc_add_order_item( $order_id, [ 'order_item_type' => $type ] );
|
||||
foreach ( $group_items as $item_data ) {
|
||||
$item = self::set_item(
|
||||
$item_data,
|
||||
$type,
|
||||
$order,
|
||||
$context,
|
||||
$info
|
||||
);
|
||||
|
||||
// Continue if order item creation failed.
|
||||
if ( ! $item_id ) {
|
||||
continue;
|
||||
/**
|
||||
* Action called before an item group is added to an order.
|
||||
*
|
||||
* @param \WC_Order_Item $item Order item object.
|
||||
* @param array $item_data Item data being added.
|
||||
* @param \WC_Order $order Order object.
|
||||
* @param \WPGraphQL\AppContext $context Request AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info Request ResolveInfo instance.
|
||||
*/
|
||||
do_action( "graphql_woocommerce_before_{$type}_added_to_order", $item, $item_data, $order, $context, $info );
|
||||
|
||||
if ( 0 === $item->get_id() ) {
|
||||
$order->add_item( $item );
|
||||
$order_items[ $type ][] = $item;
|
||||
} else {
|
||||
$item->save();
|
||||
$order_items[ $type ][] = $item;
|
||||
}
|
||||
|
||||
// Add input item data to order item.
|
||||
$item_keys = self::get_order_item_keys( $type );
|
||||
self::map_input_to_item( $item_id, $item_data, $item_keys, $context, $info );
|
||||
}
|
||||
|
||||
/**
|
||||
* Action called after an item group is added to an order.
|
||||
* Action called after an item group is added to an order, and before the order has been saved with the new items.
|
||||
*
|
||||
* @param array $items Item data being added.
|
||||
* @param integer $order_id ID of target order.
|
||||
* @param \WPGraphQL\AppContext $context Request AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info Request ResolveInfo instance.
|
||||
* @param array $group_items Item data being added.
|
||||
* @param \WC_Order $order Order object.
|
||||
* @param \WPGraphQL\AppContext $context Request AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info Request ResolveInfo instance.
|
||||
*/
|
||||
do_action( "graphql_woocommerce_after_{$type}s_added_to_order", $items, $order_id, $context, $info );
|
||||
do_action( "graphql_woocommerce_after_{$type}s_added_to_order", $group_items, $order, $context, $info );
|
||||
}//end if
|
||||
}//end foreach
|
||||
|
||||
/**
|
||||
* Action called after all items have been added and right before the new items have been saved.
|
||||
*
|
||||
* @param array<string, array<\WC_Order_Item>> $order_items Order items.
|
||||
* @param \WC_Order $order WC_Order instance.
|
||||
* @param array $input Input data describing order.
|
||||
* @param \WPGraphQL\AppContext $context Request AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info Request ResolveInfo instance.
|
||||
*/
|
||||
do_action( 'graphql_woocommerce_before_new_order_items_save', $order_items, $order, $input, $context, $info );
|
||||
|
||||
$order->save();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array<string, mixed> $item_data Item data.
|
||||
* @param string $type Item type.
|
||||
* @param \WC_Order $order Order object.
|
||||
* @param \WPGraphQL\AppContext $context AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info ResolveInfo instance.
|
||||
*
|
||||
* @return \WC_Order_Item
|
||||
*/
|
||||
public static function set_item( $item_data, $type, $order, $context, $info ) {
|
||||
$item_id = ! empty( $item_data['id'] ) ? $item_data['id'] : 0;
|
||||
$item_class = self::get_order_item_classname( $type, $item_id );
|
||||
|
||||
/** @var \WC_Order_Item $item */
|
||||
$item = new $item_class( $item_id );
|
||||
|
||||
/**
|
||||
* Filter the order item object before it is created.
|
||||
*
|
||||
* @param \WC_Order_Item $item Order item object.
|
||||
* @param array $item_data Item data.
|
||||
* @param \WC_Order $order Order object.
|
||||
* @param \WPGraphQL\AppContext $context AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info ResolveInfo instance.
|
||||
*/
|
||||
$item = apply_filters( "graphql_create_order_{$type}_object", $item, $item_data, $order, $context, $info );
|
||||
|
||||
self::map_input_to_item( $item, $item_data, $type );
|
||||
|
||||
/**
|
||||
* Action called after an order item is created.
|
||||
*
|
||||
* @param \WC_Order_Item $item Order item object.
|
||||
* @param array $item_data Item data.
|
||||
* @param \WC_Order $order Order object.
|
||||
* @param \WPGraphQL\AppContext $context AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info ResolveInfo instance.
|
||||
*/
|
||||
do_action( "graphql_create_order_{$type}", $item, $item_data, $order, $context, $info );
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order item class name.
|
||||
*
|
||||
* @param string $type Order item type.
|
||||
* @param int $id Order item ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_order_item_classname( $type, $id = 0 ) {
|
||||
$classname = false;
|
||||
switch ( $type ) {
|
||||
case 'line_item':
|
||||
case 'product':
|
||||
$classname = 'WC_Order_Item_Product';
|
||||
break;
|
||||
case 'coupon':
|
||||
$classname = 'WC_Order_Item_Coupon';
|
||||
break;
|
||||
case 'fee':
|
||||
$classname = 'WC_Order_Item_Fee';
|
||||
break;
|
||||
case 'shipping':
|
||||
$classname = 'WC_Order_Item_Shipping';
|
||||
break;
|
||||
case 'tax':
|
||||
$classname = 'WC_Order_Item_Tax';
|
||||
break;
|
||||
}
|
||||
|
||||
$classname = apply_filters( 'woocommerce_get_order_item_classname', $classname, $type, $id ); // phpcs:ignore WordPress.NamingConventions
|
||||
|
||||
return $classname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of item mapped with the provided $item_keys and extracts $meta_data
|
||||
*
|
||||
* @param integer $item_id Order item ID.
|
||||
* @param array $input Item input data.
|
||||
* @param array $item_keys Item key map.
|
||||
* @param \WPGraphQL\AppContext $context AppContext instance.
|
||||
* @param \GraphQL\Type\Definition\ResolveInfo $info ResolveInfo instance.
|
||||
* @param \WC_Order_Item &$item Order item.
|
||||
* @param array $input Item input data.
|
||||
* @param string $type Item type.
|
||||
*
|
||||
* @throws \Exception Failed to retrieve order item | Failed to retrieve connected product.
|
||||
* @throws \Exception Failed to retrieve connected product.
|
||||
*
|
||||
* @return int
|
||||
* @return void
|
||||
*/
|
||||
protected static function map_input_to_item( $item_id, $input, $item_keys, $context, $info ) {
|
||||
$order_item = \WC_Order_Factory::get_order_item( $item_id );
|
||||
if ( ! is_object( $order_item ) ) {
|
||||
throw new \Exception( __( 'Failed to retrieve order item.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
protected static function map_input_to_item( &$item, $input, $type ) {
|
||||
$item_keys = self::get_order_item_keys( $type );
|
||||
|
||||
$args = [];
|
||||
$meta_data = null;
|
||||
@@ -203,10 +312,9 @@ class Order_Mutation {
|
||||
}
|
||||
|
||||
// Calculate to subtotal/total for line items.
|
||||
|
||||
if ( isset( $args['quantity'] ) ) {
|
||||
$product = ( ! empty( $order_item['product_id'] ) )
|
||||
? wc_get_product( $order_item['product_id'] )
|
||||
$product = ( ! empty( $item['product_id'] ) )
|
||||
? wc_get_product( $item['product_id'] )
|
||||
: wc_get_product( self::get_product_id( $args ) );
|
||||
if ( ! is_object( $product ) ) {
|
||||
throw new \Exception( __( 'Failed to retrieve product connected to order item.', 'wp-graphql-woocommerce' ) );
|
||||
@@ -219,18 +327,24 @@ class Order_Mutation {
|
||||
|
||||
// Set item props.
|
||||
foreach ( $args as $key => $value ) {
|
||||
if ( is_callable( [ $order_item, "set_{$key}" ] ) ) {
|
||||
$order_item->{"set_{$key}"}( $value );
|
||||
if ( is_callable( [ $item, "set_{$key}" ] ) ) {
|
||||
$item->{"set_{$key}"}( $value );
|
||||
}
|
||||
}
|
||||
|
||||
// Update item meta data if any is found.
|
||||
if ( 0 !== $item_id && ! empty( $meta_data ) ) {
|
||||
// Update item meta data.
|
||||
self::update_item_meta_data( $item_id, $meta_data, $context, $info );
|
||||
if ( empty( $meta_data ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $order_item->save();
|
||||
foreach ( $meta_data as $entry ) {
|
||||
$exists = $item->get_meta( $entry['key'], true, 'edit' );
|
||||
if ( '' !== $exists && $exists !== $entry['value'] ) {
|
||||
$item->update_meta_data( $entry['key'], $entry['value'] );
|
||||
} else {
|
||||
$item->add_meta_data( $entry['key'], $entry['value'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,10 +399,10 @@ class Order_Mutation {
|
||||
protected static function get_product_id( $data ) {
|
||||
if ( ! empty( $data['sku'] ) ) {
|
||||
$product_id = (int) wc_get_product_id_by_sku( $data['sku'] );
|
||||
} elseif ( ! empty( $data['product_id'] ) && empty( $data['variation_id'] ) ) {
|
||||
$product_id = (int) $data['product_id'];
|
||||
} elseif ( ! empty( $data['variation_id'] ) ) {
|
||||
$product_id = (int) $data['variation_id'];
|
||||
} elseif ( ! empty( $data['product_id'] ) ) {
|
||||
$product_id = (int) $data['product_id'];
|
||||
} else {
|
||||
throw new UserError( __( 'Product ID or SKU is required.', 'wp-graphql-woocommerce' ) );
|
||||
}
|
||||
|
||||
@@ -497,7 +497,7 @@ class Order extends Model {
|
||||
return ! empty( $this->data->get_date_paid() ) ? $this->data->get_date_paid() : null;
|
||||
},
|
||||
'subtotal' => function () {
|
||||
return ! empty( $this->data->get_subtotal() )
|
||||
return ! is_null( $this->data->get_subtotal() )
|
||||
? wc_graphql_price( $this->data->get_subtotal(), [ 'currency' => $this->data->get_currency() ] )
|
||||
: null;
|
||||
},
|
||||
|
||||
@@ -143,10 +143,14 @@ class OrderFactory extends \WP_UnitTest_Factory_For_Thing {
|
||||
public function add_line_item( $order, $args = [], $save = true ) {
|
||||
$order = $save ? \wc_get_order( $order ) : $order;
|
||||
|
||||
if ( empty( $args['product'] ) ) {
|
||||
$product = \wc_get_product( $this->factory->product->createSimple() );
|
||||
} else {
|
||||
if ( ! empty( $args['variation_id'] ) ) {
|
||||
$product = \wc_get_product( $args['variation_id'] );
|
||||
} elseif ( ! empty( $args['product_id'] ) ) {
|
||||
$product = \wc_get_product( $args['product_id'] );
|
||||
} elseif ( ! empty( $args['product'] ) ) {
|
||||
$product = \wc_get_product( $args['product'] );
|
||||
} else {
|
||||
$product = \wc_get_product( $this->factory->product->createSimple() );
|
||||
}
|
||||
|
||||
if ( empty( $args['qty'] ) ) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
class IntrospectionQueryTest extends \Codeception\TestCase\WPTestCase {
|
||||
class IntrospectionQueryTest extends \Tests\WPGraphQL\WooCommerce\TestCase\WooGraphQLTestCase {
|
||||
public function setUp(): void {
|
||||
// before
|
||||
parent::setUp();
|
||||
@@ -17,17 +17,19 @@ class IntrospectionQueryTest extends \Codeception\TestCase\WPTestCase {
|
||||
// Validate schema.
|
||||
public function testSchema() {
|
||||
try {
|
||||
$request = new \WPGraphQL\Request();
|
||||
$request->schema->assertValid();
|
||||
new \WPGraphQL\Request();
|
||||
|
||||
$schema = WPGraphQL::get_schema();
|
||||
$schema->assertValid();
|
||||
|
||||
// Assert true upon success.
|
||||
$this->assertTrue( true );
|
||||
$this->assertTrue( true, 'Schema is valid.' );
|
||||
} catch ( \GraphQL\Error\InvariantViolation $e ) {
|
||||
// use --debug flag to view.
|
||||
codecept_debug( $e->getMessage() );
|
||||
$this->logData( $e->getMessage() );
|
||||
|
||||
// Fail upon throwing
|
||||
$this->assertTrue( false );
|
||||
$this->assertTrue( false, $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user