Skip to content

Commit 7c10a3d

Browse files
committed
fix: ID resolution made consistent across all edit and delete node mutations
1 parent 594bc29 commit 7c10a3d

12 files changed

+99
-100
lines changed

includes/data/mutation/class-order-mutation.php

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace WPGraphQL\WooCommerce\Data\Mutation;
1010

1111
use GraphQL\Error\UserError;
12+
use WPGraphQL\Utils\Utils;
1213

1314

1415
/**
@@ -34,18 +35,24 @@ public static function authorized( $input, $context, $info, $mutation = 'create'
3435
*/
3536
$post_type_object = get_post_type_object( 'shop_order' );
3637

37-
return apply_filters(
38-
"graphql_woocommerce_authorized_to_{$mutation}_orders",
39-
current_user_can(
40-
'delete' === $mutation
41-
? $post_type_object->cap->delete_posts
42-
: $post_type_object->cap->edit_posts
43-
),
44-
$order_id,
45-
$input,
46-
$context,
47-
$info
48-
);
38+
if ( $order_id === null ) {
39+
return apply_filters(
40+
"graphql_woocommerce_authorized_to_{$mutation}_orders",
41+
current_user_can($post_type_object->cap->edit_posts),
42+
$order_id,
43+
$input,
44+
$context,
45+
$info
46+
);
47+
}
48+
49+
$order = \wc_get_order( $order_id );
50+
$post_type = get_post_type( $order_id );
51+
52+
// Return true if user is owner or admin
53+
$is_owner = 0 !== get_current_user_id() && $order->get_customer_id() === get_current_user_id();
54+
$is_admin = \wc_rest_check_post_permissions( $post_type, 'edit', $order_id );
55+
return $is_owner || $is_admin;
4956
}
5057

5158
/**
@@ -565,25 +572,26 @@ public static function apply_coupons( $order_id, $coupons ) {
565572
/**
566573
* Validates order customer
567574
*
568-
* @param array $input Input data describing order.
575+
* @param string $customer_id ID of customer for order.
569576
*
570577
* @return bool
571578
*/
572-
public static function validate_customer( $input ) {
573-
if ( ! empty( $input['customerId'] ) ) {
574-
// Make sure customer exists.
575-
if ( false === get_user_by( 'id', $input['customerId'] ) ) {
576-
return false;
577-
}
578-
// Make sure customer is part of blog.
579-
if ( is_multisite() && ! is_user_member_of_blog( $input['customerId'] ) ) {
580-
add_user_to_blog( get_current_blog_id(), $input['customerId'], 'customer' );
581-
}
579+
public static function validate_customer( $customer_id ) {
580+
$id = Utils::get_database_id_from_id( $customer_id );
581+
if ( ! $id ) {
582+
return false;
583+
}
582584

583-
return true;
585+
if ( false === get_user_by( 'id', $id ) ) {
586+
return false;
584587
}
585588

586-
return false;
589+
// Make sure customer is part of blog.
590+
if ( is_multisite() && ! is_user_member_of_blog( $id ) ) {
591+
add_user_to_blog( get_current_blog_id(), $id, 'customer' );
592+
}
593+
594+
return true;
587595
}
588596

589597
/**

includes/mutation/class-coupon-create.php

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
use GraphQL\Error\UserError;
1414
use GraphQL\Type\Definition\ResolveInfo;
15-
use GraphQLRelay\Relay;
1615
use WPGraphQL\AppContext;
1716
use WPGraphQL\WooCommerce\Data\Mutation\Coupon_Mutation;
1817
use WPGraphQL\WooCommerce\Model\Coupon;
18+
use WPGraphQL\Utils\Utils;
1919

2020
/**
2121
* Class Coupon_Create
@@ -163,16 +163,14 @@ public static function get_output_fields() {
163163
*/
164164
public static function mutate_and_get_payload( $input, AppContext $context, ResolveInfo $info ) {
165165
// Retrieve order ID.
166-
$coupon_id = 0;
167-
if ( ! empty( $input['id'] ) && is_numeric( $input['id'] ) ) {
168-
$coupon_id = absint( $input['id'] );
169-
} elseif ( ! empty( $input['id'] ) ) {
170-
$id_components = Relay::fromGlobalId( $input['id'] );
171-
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
172-
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
173-
}
166+
if ( ! empty ( $input['id'] ) ) {
167+
$coupon_id = Utils::get_database_id_from_id( $input['id'] );
168+
} else {
169+
$coupon_id = 0;
170+
}
174171

175-
$coupon_id = absint( $id_components['id'] );
172+
if ( false === $coupon_id ) {
173+
throw new UserError( __( 'Coupon ID provided is invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
176174
}
177175

178176
$coupon = new \WC_Coupon( $coupon_id );

includes/mutation/class-coupon-delete.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313
use GraphQL\Error\UserError;
1414
use GraphQL\Type\Definition\ResolveInfo;
15-
use GraphQLRelay\Relay;
1615
use WPGraphQL\AppContext;
1716
use WPGraphQL\WooCommerce\Model\Coupon;
17+
use WPGraphQL\Utils\Utils;
1818

1919
/**
2020
* Class Coupon_Delete
@@ -87,17 +87,11 @@ public static function get_output_fields() {
8787
*/
8888
public static function mutate_and_get_payload( $input, AppContext $context, ResolveInfo $info ) {
8989
// Retrieve order ID.
90-
$coupon_id = 0;
91-
if ( ! empty( $input['id'] ) && is_numeric( $input['id'] ) ) {
92-
$coupon_id = absint( $input['id'] );
93-
} elseif ( ! empty( $input['id'] ) ) {
94-
$id_components = Relay::fromGlobalId( $input['id'] );
95-
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
96-
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
97-
}
98-
99-
$coupon_id = absint( $id_components['id'] );
90+
$coupon_id = Utils::get_database_id_from_id( $input['id'] );
91+
if ( empty( $coupon_id ) ) {
92+
throw new UserError( __( 'Coupon ID provided is missing or invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
10093
}
94+
10195
$coupon = new Coupon( $coupon_id );
10296

10397
if ( ! $coupon->ID ) {

includes/mutation/class-order-create.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public static function mutate_and_get_payload() {
167167
WC()->payment_gateways();
168168

169169
// Validate customer ID, if set.
170-
if ( ! empty( $input['customerId'] ) && ! Order_Mutation::validate_customer( $input ) ) {
170+
if ( ! empty( $input['customerId'] ) && ! Order_Mutation::validate_customer( $input['customerId'] ) ) {
171171
throw new UserError( __( 'Customer ID is invalid.', 'wp-graphql-woocommerce' ) );
172172
}
173173

includes/mutation/class-order-delete-items.php

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
use GraphQL\Error\UserError;
1414
use GraphQL\Type\Definition\ResolveInfo;
15-
use GraphQLRelay\Relay;
1615
use WPGraphQL\AppContext;
1716
use WPGraphQL\WooCommerce\Data\Mutation\Order_Mutation;
1817
use WPGraphQL\WooCommerce\Model\Order;
18+
use WPGraphQL\Utils\Utils;
1919

2020
/**
2121
* Class Order_Delete_Items
@@ -45,13 +45,14 @@ public static function register_mutation() {
4545
public static function get_input_fields() {
4646
return array_merge(
4747
[
48-
'id' => [
48+
'id' => [
4949
'type' => 'ID',
50-
'description' => __( 'Order global ID', 'wp-graphql-woocommerce' ),
50+
'description' => __( 'Database ID or global ID of the order', 'wp-graphql-woocommerce' ),
5151
],
52-
'orderId' => [
53-
'type' => 'Int',
54-
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
52+
'orderId' => [
53+
'type' => 'Int',
54+
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
55+
'deprecationReason' => __( 'Use "id" field instead.', 'wp-graphql-woocommerce' ),
5556
],
5657
'itemIds' => [
5758
'type' => [ 'list_of' => 'Int' ],
@@ -87,20 +88,16 @@ public static function mutate_and_get_payload() {
8788
// Retrieve order ID.
8889
$order_id = null;
8990
if ( ! empty( $input['id'] ) ) {
90-
$id_components = Relay::fromGlobalId( $input['id'] );
91-
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
92-
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
93-
}
94-
$order_id = absint( $id_components['id'] );
91+
$order_id = Utils::get_database_id_from_id( $input['id'] );
9592
} elseif ( ! empty( $input['orderId'] ) ) {
9693
$order_id = absint( $input['orderId'] );
9794
} else {
98-
throw new UserError( __( 'No order ID provided.', 'wp-graphql-woocommerce' ) );
95+
throw new UserError( __( 'Order ID provided is missing or invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
9996
}
10097

10198
// Check if authorized to delete items on this order.
10299
if ( ! Order_Mutation::authorized( $input, $context, $info, 'delete-items', $order_id ) ) {
103-
throw new UserError( __( 'User does not have the capabilities necessary to delete an order.', 'wp-graphql-woocommerce' ) );
100+
throw new UserError( __( 'User does not have the capabilities necessary to delete order items.', 'wp-graphql-woocommerce' ) );
104101
}
105102

106103
// Confirm item IDs.

includes/mutation/class-order-delete.php

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212

1313
use GraphQL\Error\UserError;
1414
use GraphQL\Type\Definition\ResolveInfo;
15-
use GraphQLRelay\Relay;
1615
use WC_Order_Factory;
1716
use WPGraphQL\AppContext;
1817
use WPGraphQL\WooCommerce\Data\Mutation\Order_Mutation;
1918
use WPGraphQL\WooCommerce\Model\Order;
19+
use WPGraphQL\Utils\Utils;
2020

2121
/**
2222
* Class Order_Delete
@@ -48,11 +48,12 @@ public static function get_input_fields() {
4848
[
4949
'id' => [
5050
'type' => 'ID',
51-
'description' => __( 'Order global ID', 'wp-graphql-woocommerce' ),
51+
'description' => __( 'Database ID or global ID of the order', 'wp-graphql-woocommerce' ),
5252
],
5353
'orderId' => [
54-
'type' => 'Int',
55-
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
54+
'type' => 'Int',
55+
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
56+
'deprecationReason' => __( 'Use "id" field instead.', 'wp-graphql-woocommerce' ),
5657
],
5758
'forceDelete' => [
5859
'type' => 'Boolean',
@@ -88,15 +89,11 @@ public static function mutate_and_get_payload() {
8889
// Retrieve order ID.
8990
$order_id = null;
9091
if ( ! empty( $input['id'] ) ) {
91-
$id_components = Relay::fromGlobalId( $input['id'] );
92-
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
93-
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
94-
}
95-
$order_id = absint( $id_components['id'] );
92+
$order_id = Utils::get_database_id_from_id( $input['id'] );
9693
} elseif ( ! empty( $input['orderId'] ) ) {
9794
$order_id = absint( $input['orderId'] );
9895
} else {
99-
throw new UserError( __( 'No order ID provided.', 'wp-graphql-woocommerce' ) );
96+
throw new UserError( __( 'Order ID provided is missing or invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
10097
}
10198

10299
// Check if authorized to delete this order.

includes/mutation/class-order-update.php

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212

1313
use GraphQL\Error\UserError;
1414
use GraphQL\Type\Definition\ResolveInfo;
15-
use GraphQLRelay\Relay;
1615
use WC_Order_Factory;
1716
use WPGraphQL\AppContext;
1817
use WPGraphQL\WooCommerce\Data\Mutation\Order_Mutation;
1918
use WPGraphQL\WooCommerce\Model\Order;
19+
use WPGraphQL\Utils\Utils;
2020

2121
/**
2222
* Class Order_Update
@@ -49,15 +49,16 @@ public static function get_input_fields() {
4949
[
5050
'id' => [
5151
'type' => 'ID',
52-
'description' => __( 'Order global ID', 'wp-graphql-woocommerce' ),
52+
'description' => __( 'Database ID or global ID of the order', 'wp-graphql-woocommerce' ),
5353
],
54-
'orderId' => [
55-
'type' => 'Int',
56-
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
54+
'orderId' => [
55+
'type' => 'Int',
56+
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
57+
'deprecationReason' => __( 'Use "id" field instead.', 'wp-graphql-woocommerce' ),
5758
],
5859
'customerId' => [
59-
'type' => 'Int',
60-
'description' => __( 'Order customer ID', 'wp-graphql-woocommerce' ),
60+
'type' => 'ID',
61+
'description' => __( 'Database ID or global ID of the customer for the order', 'wp-graphql-woocommerce' ),
6162
],
6263
]
6364
);
@@ -89,17 +90,13 @@ public static function mutate_and_get_payload() {
8990
// Retrieve order ID.
9091
$order_id = null;
9192
if ( ! empty( $input['id'] ) ) {
92-
$id_components = Relay::fromGlobalId( $input['id'] );
93-
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
94-
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
95-
}
96-
$order_id = absint( $id_components['id'] );
93+
$order_id = Utils::get_database_id_from_id( $input['id'] );
9794
} elseif ( ! empty( $input['orderId'] ) ) {
9895
$order_id = absint( $input['orderId'] );
9996
} else {
100-
throw new UserError( __( 'No order ID provided.', 'wp-graphql-woocommerce' ) );
97+
throw new UserError( __( 'Order ID provided is missing or invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
10198
}
102-
99+
103100
// Check if authorized to update this order.
104101
if ( ! Order_Mutation::authorized( $input, $context, $info, 'update', $order_id ) ) {
105102
throw new UserError( __( 'User does not have the capabilities necessary to update an order.', 'wp-graphql-woocommerce' ) );
@@ -133,7 +130,7 @@ public static function mutate_and_get_payload() {
133130
\WC()->payment_gateways();
134131

135132
// Validate customer ID.
136-
if ( ! empty( $input['customerId'] ) && ! Order_Mutation::validate_customer( $input ) ) {
133+
if ( ! empty( $input['customerId'] ) && ! Order_Mutation::validate_customer( $input['customerId'] ) ) {
137134
throw new UserError( __( 'New customer ID is invalid.', 'wp-graphql-woocommerce' ) );
138135
}
139136

@@ -147,7 +144,7 @@ public static function mutate_and_get_payload() {
147144
}
148145

149146
// Actions for after the order is saved.
150-
if ( true === $input['isPaid'] ) {
147+
if ( isset( $input['isPaid'] ) && true === $input['isPaid'] ) {
151148
$order->payment_complete(
152149
! empty( $input['transactionId'] )
153150
? $input['transactionId']

includes/mutation/class-review-delete-restore.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use GraphQL\Type\Definition\ResolveInfo;
1515
use GraphQLRelay\Relay;
1616
use WPGraphQL\AppContext;
17+
use WPGraphQL\Utils\Utils;
1718

1819
/**
1920
* Class Review_Delete_Restore
@@ -130,12 +131,12 @@ public static function get_output_fields( $restore = false ) {
130131
public static function mutate_and_get_payload() {
131132
return static function ( $input, AppContext $context, ResolveInfo $info ) {
132133
// Retrieve the product review rating for the payload.
133-
$id_parts = Relay::fromGlobalId( $input['id'] );
134-
if ( empty( $id_parts['id'] ) ) {
134+
$id = Utils::get_database_id_from_id( $input['id'] );
135+
if ( ! $id ) {
135136
throw new UserError( __( 'Invalid Product Review ID provided', 'wp-graphql-woocommerce' ) );
136137
}
137138

138-
$rating = get_comment_meta( absint( $id_parts['id'] ), 'rating' );
139+
$rating = get_comment_meta( absint( $id ), 'rating' );
139140

140141
// @codingStandardsIgnoreLine
141142
switch ( $info->fieldName ) {

includes/mutation/class-review-update.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use GraphQLRelay\Relay;
1616
use WPGraphQL\AppContext;
1717
use WPGraphQL\Mutation\CommentUpdate;
18+
use WPGraphQL\Utils\Utils;
1819

1920
/**
2021
* Class Review_Update
@@ -80,11 +81,9 @@ public static function mutate_and_get_payload() {
8081
];
8182

8283
$payload = [];
83-
$id_parts = ! empty( $input['id'] ) ? Relay::fromGlobalId( $input['id'] ) : null;
84-
$payload['id'] = isset( $id_parts['id'] ) && absint( $id_parts['id'] ) ? absint( $id_parts['id'] ) : null;
85-
86-
if ( empty( $payload['id'] ) ) {
87-
throw new UserError( __( 'The Review could not be updated', 'wp-graphql-woocommerce' ) );
84+
$id = Utils::get_database_id_from_id( $input['id'] );
85+
if ( ! $id ) {
86+
throw new UserError( __( 'Provided review ID missing or invalid ', 'wp-graphql-woocommerce' ) );
8887
}
8988

9089
if ( array_intersect_key( $input, $skip ) !== $input ) {

0 commit comments

Comments
 (0)