Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deleteOrder mutation #99

Merged
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
2 changes: 2 additions & 0 deletions includes/class-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
use WPGraphQL\Extensions\WooCommerce\Mutation\Cart_Add_Fee;
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Create;
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Update;
use WPGraphQL\Extensions\WooCommerce\Mutation\Order_Delete;

/**
* Class Actions
Expand Down Expand Up @@ -165,5 +166,6 @@ public static function graphql_register_types() {
Cart_Add_Fee::register_mutation();
Order_Create::register_mutation();
Order_Update::register_mutation();
Order_Delete::register_mutation();
}
}
75 changes: 70 additions & 5 deletions includes/data/mutation/class-order-mutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@
* Class - Order_Mutation
*/
class Order_Mutation {
/**
* Filterable authentication function.
*
* @param string $mutation Mutation being executed.
* @param array $input Input data describing order.
* @param AppContext $context AppContext instance.
* @param ResolveInfo $info ResolveInfo instance.
*
* @return boolean
*/
public static function authorized( $mutation = 'create', $input, $context, $info ) {
$post_type_object = get_post_type_object( 'shop_order' );

return apply_filters(
"authorized_to_{$mutation}_orders",
! current_user_can( $post_type_object->cap->create_posts ),
$input,
$context,
$info
);
}

/**
* Create an order.
*
Expand Down Expand Up @@ -42,11 +64,31 @@ public static function create_order( $input, $context, $info ) {
}
}

/**
* Action called before order is created.
*
* @param WC_Order $order WC_Order instance.
* @param array $input Input data describing order.
* @param AppContext $context Request AppContext instance.
* @param ResolveInfo $info Request ResolveInfo instance.
*/
do_action( 'woocommerce_graphql_before_order_create', $input, $context, $info );

$order = \wc_create_order( $args );
if ( is_wp_error( $order ) ) {
throw UserError( $order->get_error_code() . $order->get_message() );
}

/**
* Action called after order is created.
*
* @param WC_Order $order WC_Order instance.
* @param array $input Input data describing order.
* @param AppContext $context Request AppContext instance.
* @param ResolveInfo $info Request ResolveInfo instance.
*/
do_action( 'woocommerce_graphql_after_order_create', $order, $input, $context, $info );

return $order->get_id();
}

Expand All @@ -69,6 +111,17 @@ public static function add_items( $input, $order_id, $context, $info ) {
foreach ( $input as $key => $items ) {
if ( array_key_exists( $key, $item_group_keys ) ) {
$type = $item_group_keys[ $key ];

/**
* 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 AppContext $context Request AppContext instance.
* @param ResolveInfo $info Request ResolveInfo instance.
*/
do_action( "woocommerce_graphql_before_{$type}s_added_to_order", $items, $order_id, $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'] ) )
Expand All @@ -84,6 +137,16 @@ public static function add_items( $input, $order_id, $context, $info ) {
$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.
*
* @param array $items Item data being added.
* @param integer $order_id ID of target order.
* @param AppContext $context Request AppContext instance.
* @param ResolveInfo $info Request ResolveInfo instance.
*/
do_action( "woocommerce_graphql_after_{$type}s_added_to_order", $items, $order_id, $context, $info );
}
}
}
Expand Down Expand Up @@ -255,7 +318,7 @@ public static function add_order_meta( $order_id, $input, $context, $info ) {
}

/**
* Action called before order meta saved.
* Action called before changes to order meta are saved.
*
* @param WC_Order $order WC_Order instance.
* @param array $props Order props array.
Expand Down Expand Up @@ -337,13 +400,15 @@ public static function validate_customer( $input ) {
/**
* Purge object when creating.
*
* @param WC_Order $order Object data.
* @param WC_Order|Order $order Object data.
* @param boolean $force_delete Delete or put in trash.
*
* @return bool
* @throws UserError Failed to delete order.
*/
public static function purge( $order ) {
if ( $order instanceof WC_Order ) {
return $order->delete( true );
public static function purge( $order, $force_delete = true ) {
if ( is_callable( array( $order, 'delete' ) ) ) {
return $order->delete( $force_delete );
}

return false;
Expand Down
22 changes: 22 additions & 0 deletions includes/model/class-crud-cpt.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace WPGraphQL\Extensions\WooCommerce\Model;

use GraphQL\Error\UserError;
use WPGraphQL\Model\Model;

/**
Expand Down Expand Up @@ -88,6 +89,27 @@ protected function is_private() {
return false;
}

/**
* Wrapper function for deleting
*
* @param boolean $force_delete Should the data be deleted permanently.
*
* @return boolean
* @throws UserError Not authorized.
kidunot89 marked this conversation as resolved.
Show resolved Hide resolved
*/
public function delete( $force_delete = false ) {
if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) {
throw new UserError(
__(
'User does not have the capabilities necessary to delete this object.',
'wp-graphql-woocommerce'
)
);
}

return $this->data->delete( $force_delete );
}

/**
* Retrieve the cap to check if the data should be restricted for the crud object
*
Expand Down
2 changes: 1 addition & 1 deletion includes/model/class-order.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ protected function init() {
return ! is_null( $this->data->needs_processing() ) ? $this->data->needs_processing() : null;
},
'downloadableItems' => function() {
return ! is_null( $this->data->get_downloadable_items() ) ? $this->data->get_downloadable_items() : null;
return ! empty( $this->data->get_downloadable_items() ) ? $this->data->get_downloadable_items() : null;
},
/**
* Connection resolvers fields
Expand Down
16 changes: 12 additions & 4 deletions includes/mutation/class-order-create.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,8 @@ public static function get_output_fields() {
*/
public static function mutate_and_get_payload() {
return function( $input, AppContext $context, ResolveInfo $info ) {
$post_type_object = get_post_type_object( 'shop_order' );

if ( ! current_user_can( $post_type_object->cap->create_posts ) ) {
throw new UserError( __( 'Sorry, you are not allowed to create a new order.', 'wp-graphql-woocommerce' ) );
if ( Order_Mutation::authorized( 'create', $input, $context, $info ) ) {
throw new UserError( __( 'User does not have the capabilities necessary to create an order.', 'wp-graphql-woocommerce' ) );
}

// Create order.
Expand Down Expand Up @@ -181,6 +179,16 @@ public static function mutate_and_get_payload() {
);
}

/**
* Action called after order is created.
*
* @param WC_Order $order WC_Order instance.
* @param array $input Input data describing order.
* @param AppContext $context Request AppContext instance.
* @param ResolveInfo $info Request ResolveInfo instance.
*/
do_action( 'woocommerce_graphql_after_order_create', $order, $input, $context, $info );

return array( 'id' => $order->get_id() );
} catch ( \Exception $e ) {
Order_Mutation::purge( $order );
Expand Down
159 changes: 159 additions & 0 deletions includes/mutation/class-order-delete.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<?php
/**
* Mutation - deleteOrder
*
* Registers mutation for delete an order.
*
* @package WPGraphQL\Extensions\WooCommerce\Mutation
* @since 0.2.0
*/

namespace WPGraphQL\Extensions\WooCommerce\Mutation;

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

/**
* Class Order_Delete
*/
class Order_Delete {
/**
* Registers mutation
*/
public static function register_mutation() {
register_graphql_mutation(
'deleteOrder',
array(
'inputFields' => self::get_input_fields(),
'outputFields' => self::get_output_fields(),
'mutateAndGetPayload' => self::mutate_and_get_payload(),
)
);
}

/**
* Defines the mutation input field configuration
*
* @return array
*/
public static function get_input_fields() {
$input_fields = array_merge(
array(
'id' => array(
'type' => 'ID',
'description' => __( 'Order global ID', 'wp-graphql-woocommerce' ),
),
'orderId' => array(
'type' => 'Int',
'description' => __( 'Order WP ID', 'wp-graphql-woocommerce' ),
),
'forceDelete' => array(
'type' => 'Boolean',
'description' => __( 'Delete or simply place in trash.', 'wp-graphql-woocommerce' ),
),
)
);

return $input_fields;
}

/**
* Defines the mutation output field configuration
*
* @return array
*/
public static function get_output_fields() {
return array(
'order' => array(
'type' => 'Order',
'resolve' => function( $payload ) {
return $payload['order'];
},
),
);
}

/**
* Defines the mutation data modification closure.
*
* @return callable
*/
public static function mutate_and_get_payload() {
return function( $input, AppContext $context, ResolveInfo $info ) {
if ( Order_Mutation::authorized( 'delete', $input, $context, $info ) ) {
throw new UserError( __( 'User does not have the capabilities necessary to delete an order.', 'wp-graphql-woocommerce' ) );
}

// 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'] );
} elseif ( ! empty( $input['orderId'] ) ) {
$order_id = absint( $input['orderId'] );
} else {
throw new UserError( __( 'No order ID provided.', 'wp-graphql-woocommerce' ) );
}

$force_delete = false;
if ( ! empty( $input['forceDelete'] ) ) {
$force_delete = $input['forceDelete'];
}

// Get Order model instance for output.
$order = new Order( $order_id );

// Cache items to prevent null value errors.
// @codingStandardsIgnoreStart
$order->downloadableItems;
$order->get_items();
$order->get_items( 'fee' );
$order->get_items( 'shipping' );
$order->get_items( 'tax' );
$order->get_items( 'coupon' );
// @codingStandardsIgnoreEnd.

/**
* Action called before order is deleted.
*
* @param WC_Order $order WC_Order instance.
* @param array $input Input data describing order.
* @param AppContext $context Request AppContext instance.
* @param ResolveInfo $info Request ResolveInfo instance.
*/
do_action( 'woocommerce_graphql_before_order_delete', $order, $input, $context, $info );

// Delete order.
$success = Order_Mutation::purge( \WC_Order_Factory::get_order( $order->ID ), $force_delete );

if ( ! $success ) {
throw new UserError(
sprintf(
/* translators: Deletion failed message */
__( 'Removal of Order %d failed', 'wp-graphql-woocommerce' ),
$order->get_id()
)
);
}

/**
* Action called before order is deleted.
*
* @param WC_Order $order WC_Order instance.
* @param array $input Input data describing order
* @param AppContext $context Request AppContext instance.
* @param ResolveInfo $info Request ResolveInfo instance.
*/
do_action( 'woocommerce_graphql_after_order_delete', $order, $input, $context, $info );

return array( 'order' => $order );
};
}
}
Loading