Skip to content

Commit

Permalink
fix: ID resolution made consistent across all edit and delete node mu… (
Browse files Browse the repository at this point in the history
#902)

* fix: ID resolution made consistent across all edit and delete node mutations

* chore: linter compliances met
  • Loading branch information
kidunot89 authored Nov 6, 2024
1 parent b801133 commit 32f8ba2
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 102 deletions.
77 changes: 50 additions & 27 deletions includes/data/mutation/class-order-mutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace WPGraphQL\WooCommerce\Data\Mutation;

use GraphQL\Error\UserError;
use WPGraphQL\Utils\Utils;


/**
Expand All @@ -22,8 +23,9 @@ class Order_Mutation {
* @param \WPGraphQL\AppContext $context AppContext instance.
* @param \GraphQL\Type\Definition\ResolveInfo $info ResolveInfo instance.
* @param string $mutation Mutation being executed.
* @param integer|null $order_id Order ID.
*
* @param integer|null|false $order_id Order ID.
* @throws \GraphQL\Error\UserError Error locating order.
*
* @return boolean
*/
public static function authorized( $input, $context, $info, $mutation = 'create', $order_id = null ) {
Expand All @@ -34,18 +36,38 @@ public static function authorized( $input, $context, $info, $mutation = 'create'
*/
$post_type_object = get_post_type_object( 'shop_order' );

return apply_filters(
"graphql_woocommerce_authorized_to_{$mutation}_orders",
current_user_can(
'delete' === $mutation
? $post_type_object->cap->delete_posts
: $post_type_object->cap->edit_posts
),
$order_id,
$input,
$context,
$info
);
if ( ! $order_id ) {
return apply_filters(
"graphql_woocommerce_authorized_to_{$mutation}_orders",
current_user_can( $post_type_object->cap->edit_posts ),
$order_id,
$input,
$context,
$info
);
}

/** @var false|\WC_Order $order */
$order = \wc_get_order( $order_id );
if ( false === $order ) {
throw new UserError(
sprintf(
/* translators: %d: Order ID */
__( 'Failed to find order with ID of %d.', 'wp-graphql-woocommerce' ),
$order_id
)
);
}

$post_type = get_post_type( $order_id );
if ( false === $post_type ) {
throw new UserError( __( 'Failed to identify the post type of the order.', 'wp-graphql-woocommerce' ) );
}

// Return true if user is owner or admin.
$is_owner = 0 !== get_current_user_id() && $order->get_customer_id() === get_current_user_id();
$is_admin = \wc_rest_check_post_permissions( $post_type, 'edit', $order_id );
return $is_owner || $is_admin;
}

/**
Expand Down Expand Up @@ -565,25 +587,26 @@ public static function apply_coupons( $order_id, $coupons ) {
/**
* Validates order customer
*
* @param array $input Input data describing order.
* @param string $customer_id ID of customer for order.
*
* @return bool
*/
public static function validate_customer( $input ) {
if ( ! empty( $input['customerId'] ) ) {
// Make sure customer exists.
if ( false === get_user_by( 'id', $input['customerId'] ) ) {
return false;
}
// Make sure customer is part of blog.
if ( is_multisite() && ! is_user_member_of_blog( $input['customerId'] ) ) {
add_user_to_blog( get_current_blog_id(), $input['customerId'], 'customer' );
}
public static function validate_customer( $customer_id ) {
$id = Utils::get_database_id_from_id( $customer_id );
if ( ! $id ) {
return false;
}

return true;
if ( false === get_user_by( 'id', $id ) ) {
return false;
}

return false;
// Make sure customer is part of blog.
if ( is_multisite() && ! is_user_member_of_blog( $id ) ) {
add_user_to_blog( get_current_blog_id(), $id, 'customer' );
}

return true;
}

/**
Expand Down
18 changes: 8 additions & 10 deletions includes/mutation/class-coupon-create.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

use GraphQL\Error\UserError;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQLRelay\Relay;
use WPGraphQL\AppContext;
use WPGraphQL\Utils\Utils;
use WPGraphQL\WooCommerce\Data\Mutation\Coupon_Mutation;
use WPGraphQL\WooCommerce\Model\Coupon;

Expand Down Expand Up @@ -163,16 +163,14 @@ public static function get_output_fields() {
*/
public static function mutate_and_get_payload( $input, AppContext $context, ResolveInfo $info ) {
// Retrieve order ID.
$coupon_id = 0;
if ( ! empty( $input['id'] ) && is_numeric( $input['id'] ) ) {
$coupon_id = absint( $input['id'] );
} elseif ( ! empty( $input['id'] ) ) {
$id_components = Relay::fromGlobalId( $input['id'] );
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
}
if ( ! empty( $input['id'] ) ) {
$coupon_id = Utils::get_database_id_from_id( $input['id'] );
} else {
$coupon_id = 0;
}

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

$coupon = new \WC_Coupon( $coupon_id );
Expand Down
16 changes: 5 additions & 11 deletions includes/mutation/class-coupon-delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

use GraphQL\Error\UserError;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQLRelay\Relay;
use WPGraphQL\AppContext;
use WPGraphQL\Utils\Utils;
use WPGraphQL\WooCommerce\Model\Coupon;

/**
Expand Down Expand Up @@ -87,17 +87,11 @@ public static function get_output_fields() {
*/
public static function mutate_and_get_payload( $input, AppContext $context, ResolveInfo $info ) {
// Retrieve order ID.
$coupon_id = 0;
if ( ! empty( $input['id'] ) && is_numeric( $input['id'] ) ) {
$coupon_id = absint( $input['id'] );
} elseif ( ! empty( $input['id'] ) ) {
$id_components = Relay::fromGlobalId( $input['id'] );
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
}

$coupon_id = absint( $id_components['id'] );
$coupon_id = Utils::get_database_id_from_id( $input['id'] );
if ( empty( $coupon_id ) ) {
throw new UserError( __( 'Coupon ID provided is missing or invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
}

$coupon = new Coupon( $coupon_id );

if ( ! $coupon->ID ) {
Expand Down
2 changes: 1 addition & 1 deletion includes/mutation/class-order-create.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public static function mutate_and_get_payload() {
WC()->payment_gateways();

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

Expand Down
23 changes: 12 additions & 11 deletions includes/mutation/class-order-delete-items.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

use GraphQL\Error\UserError;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQLRelay\Relay;
use WPGraphQL\AppContext;
use WPGraphQL\Utils\Utils;
use WPGraphQL\WooCommerce\Data\Mutation\Order_Mutation;
use WPGraphQL\WooCommerce\Model\Order;

Expand Down Expand Up @@ -47,11 +47,12 @@ public static function get_input_fields() {
[
'id' => [
'type' => 'ID',
'description' => __( 'Order global ID', 'wp-graphql-woocommerce' ),
'description' => __( 'Database ID or global ID of the order', 'wp-graphql-woocommerce' ),
],
'orderId' => [
'type' => 'Int',
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
'type' => 'Int',
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
'deprecationReason' => __( 'Use "id" field instead.', 'wp-graphql-woocommerce' ),
],
'itemIds' => [
'type' => [ 'list_of' => 'Int' ],
Expand Down Expand Up @@ -87,20 +88,20 @@ public static function mutate_and_get_payload() {
// Retrieve order ID.
$order_id = null;
if ( ! empty( $input['id'] ) ) {
$id_components = Relay::fromGlobalId( $input['id'] );
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
}
$order_id = absint( $id_components['id'] );
$order_id = Utils::get_database_id_from_id( $input['id'] );
} elseif ( ! empty( $input['orderId'] ) ) {
$order_id = absint( $input['orderId'] );
} else {
throw new UserError( __( 'No order ID provided.', 'wp-graphql-woocommerce' ) );
throw new UserError( __( 'Order ID provided is missing or invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
}

if ( ! $order_id ) {
throw new UserError( __( 'Order ID provided is invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
}

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

// Confirm item IDs.
Expand Down
23 changes: 12 additions & 11 deletions includes/mutation/class-order-delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

use GraphQL\Error\UserError;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQLRelay\Relay;
use WC_Order_Factory;
use WPGraphQL\AppContext;
use WPGraphQL\Utils\Utils;
use WPGraphQL\WooCommerce\Data\Mutation\Order_Mutation;
use WPGraphQL\WooCommerce\Model\Order;

Expand Down Expand Up @@ -48,11 +48,12 @@ public static function get_input_fields() {
[
'id' => [
'type' => 'ID',
'description' => __( 'Order global ID', 'wp-graphql-woocommerce' ),
'description' => __( 'Database ID or global ID of the order', 'wp-graphql-woocommerce' ),
],
'orderId' => [
'type' => 'Int',
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
'type' => 'Int',
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
'deprecationReason' => __( 'Use "id" field instead.', 'wp-graphql-woocommerce' ),
],
'forceDelete' => [
'type' => 'Boolean',
Expand Down Expand Up @@ -86,17 +87,17 @@ public static function get_output_fields() {
public static function mutate_and_get_payload() {
return static function ( $input, AppContext $context, ResolveInfo $info ) {
// Retrieve order ID.
$order_id = null;
$order_id = false;
if ( ! empty( $input['id'] ) ) {
$id_components = Relay::fromGlobalId( $input['id'] );
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
}
$order_id = absint( $id_components['id'] );
$order_id = Utils::get_database_id_from_id( $input['id'] );
} elseif ( ! empty( $input['orderId'] ) ) {
$order_id = absint( $input['orderId'] );
} else {
throw new UserError( __( 'No order ID provided.', 'wp-graphql-woocommerce' ) );
throw new UserError( __( 'Order ID provided is missing or invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
}

if ( ! $order_id ) {
throw new UserError( __( 'Order ID provided is invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
}

// Check if authorized to delete this order.
Expand Down
29 changes: 15 additions & 14 deletions includes/mutation/class-order-update.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

use GraphQL\Error\UserError;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQLRelay\Relay;
use WC_Order_Factory;
use WPGraphQL\AppContext;
use WPGraphQL\Utils\Utils;
use WPGraphQL\WooCommerce\Data\Mutation\Order_Mutation;
use WPGraphQL\WooCommerce\Model\Order;

Expand Down Expand Up @@ -49,15 +49,16 @@ public static function get_input_fields() {
[
'id' => [
'type' => 'ID',
'description' => __( 'Order global ID', 'wp-graphql-woocommerce' ),
'description' => __( 'Database ID or global ID of the order', 'wp-graphql-woocommerce' ),
],
'orderId' => [
'type' => 'Int',
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
'type' => 'Int',
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
'deprecationReason' => __( 'Use "id" field instead.', 'wp-graphql-woocommerce' ),
],
'customerId' => [
'type' => 'Int',
'description' => __( 'Order customer ID', 'wp-graphql-woocommerce' ),
'type' => 'ID',
'description' => __( 'Database ID or global ID of the customer for the order', 'wp-graphql-woocommerce' ),
],
]
);
Expand Down Expand Up @@ -89,15 +90,15 @@ public static function mutate_and_get_payload() {
// Retrieve order ID.
$order_id = null;
if ( ! empty( $input['id'] ) ) {
$id_components = Relay::fromGlobalId( $input['id'] );
if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) {
throw new UserError( __( 'The "id" provided is invalid', 'wp-graphql-woocommerce' ) );
}
$order_id = absint( $id_components['id'] );
$order_id = Utils::get_database_id_from_id( $input['id'] );
} elseif ( ! empty( $input['orderId'] ) ) {
$order_id = absint( $input['orderId'] );
} else {
throw new UserError( __( 'No order ID provided.', 'wp-graphql-woocommerce' ) );
throw new UserError( __( 'Order ID provided is missing or invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
}

if ( ! $order_id ) {
throw new UserError( __( 'Order ID provided is invalid. Please check input and try again.', 'wp-graphql-woocommerce' ) );
}

// Check if authorized to update this order.
Expand Down Expand Up @@ -133,7 +134,7 @@ public static function mutate_and_get_payload() {
\WC()->payment_gateways();

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

Expand All @@ -147,7 +148,7 @@ public static function mutate_and_get_payload() {
}

// Actions for after the order is saved.
if ( true === $input['isPaid'] ) {
if ( isset( $input['isPaid'] ) && true === $input['isPaid'] ) {
$order->payment_complete(
! empty( $input['transactionId'] )
? $input['transactionId']
Expand Down
7 changes: 4 additions & 3 deletions includes/mutation/class-review-delete-restore.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use GraphQL\Type\Definition\ResolveInfo;
use GraphQLRelay\Relay;
use WPGraphQL\AppContext;
use WPGraphQL\Utils\Utils;

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

$rating = get_comment_meta( absint( $id_parts['id'] ), 'rating' );
$rating = get_comment_meta( absint( $id ), 'rating' );

// @codingStandardsIgnoreLine
switch ( $info->fieldName ) {
Expand Down
Loading

0 comments on commit 32f8ba2

Please sign in to comment.