class-wcs-remove-item.php
6.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<?php
/**
* Subscriptions Remove Item
*
*
* @author Prospress
* @since 2.0
*/
class WCS_Remove_Item {
/**
* Initialise class hooks & filters when the file is loaded
*
* @since 2.0
*/
public static function init() {
// Check if a user is requesting to remove or re-add an item to their subscription
add_action( 'init', __CLASS__ . '::maybe_remove_or_add_item_to_subscription', 100 );
}
/**
* Returns the link used to remove an item from a subscription
*
* @param int $subscription_id
* @param int $order_item_id
* @since 2.0
*/
public static function get_remove_url( $subscription_id, $order_item_id ) {
$remove_link = add_query_arg( array( 'subscription_id' => $subscription_id, 'remove_item' => $order_item_id ) );
$remove_link = wp_nonce_url( $remove_link, $subscription_id );
return $remove_link;
}
/**
* Returns the link to undo removing an item from a subscription
*
* @param int $subscription_id
* @param int $order_item_id
* @param string $base_url
* @since 2.0
*/
public static function get_undo_remove_url( $subscription_id, $order_item_id, $base_url ) {
$undo_link = add_query_arg( array( 'subscription_id' => $subscription_id, 'undo_remove_item' => $order_item_id ), $base_url );
$undo_link = wp_nonce_url( $undo_link, $subscription_id );
return $undo_link;
}
/**
* Process the remove or re-add a line item from a subscription request.
*
* @since 2.0
*/
public static function maybe_remove_or_add_item_to_subscription() {
if ( isset( $_GET['subscription_id'] ) && ( isset( $_GET['remove_item'] ) || isset( $_GET['undo_remove_item'] ) ) && isset( $_GET['_wpnonce'] ) ) {
$subscription = ( wcs_is_subscription( $_GET['subscription_id'] ) ) ? wcs_get_subscription( $_GET['subscription_id'] ) : false;
$undo_request = ( isset( $_GET['undo_remove_item'] ) ) ? true : false;
$item_id = ( $undo_request ) ? $_GET['undo_remove_item'] : $_GET['remove_item'];
if ( false === $subscription ) {
wc_add_notice( sprintf( _x( 'Subscription #%d does not exist.', 'hash before subscription ID', 'woocommerce-subscriptions' ), $_GET['subscription_id'] ), 'error' );
wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) );
exit;
}
if ( self::validate_remove_items_request( $subscription, $item_id, $undo_request ) ) {
if ( $undo_request ) {
// handle undo request
$removed_item = WC()->session->get( 'removed_subscription_items', array() );
if ( ! empty( $removed_item[ $item_id ] ) && $subscription->id == $removed_item[ $item_id ] ) {
// restore the item
wc_update_order_item( $item_id, array( 'order_item_type' => 'line_item' ) );
unset( $removed_item[ $item_id ] );
WC()->session->set( 'removed_subscription_items', $removed_item );
// restore download permissions for this item
$line_items = $subscription->get_items();
$line_item = $line_items[ $item_id ];
$_product = $subscription->get_product_from_item( $line_item );
$product_id = wcs_get_canonical_product_id( $line_item );
if ( $_product && $_product->exists() && $_product->is_downloadable() ) {
$downloads = $_product->get_files();
foreach ( array_keys( $downloads ) as $download_id ) {
wc_downloadable_file_permission( $download_id, $product_id, $subscription, $line_item['qty'] );
}
}
// translators: 1$: product name, 2$: product id
$subscription->add_order_note( sprintf( _x( 'Customer added "%1$s" (Product ID: #%2$d) via the My Account page.', 'used in order note', 'woocommerce-subscriptions' ), wcs_get_line_item_name( $line_item ), $product_id ) );
} else {
wc_add_notice( __( 'Your request to undo your previous action was unsuccessful.', 'woocommerce-subscriptions' ) );
}
} else {
// handle remove item requests
WC()->session->set( 'removed_subscription_items', array( $item_id => $subscription->id ) );
// remove download access for the item
$line_items = $subscription->get_items();
$line_item = $line_items[ $item_id ];
$product_id = wcs_get_canonical_product_id( $line_item );
WCS_Download_Handler::revoke_downloadable_file_permission( $product_id, $subscription->id, $subscription->get_user_id() );
// remove the line item from subscription but preserve its data in the DB
wc_update_order_item( $item_id, array( 'order_item_type' => 'line_item_removed' ) );
// translators: 1$: product name, 2$: product id
$subscription->add_order_note( sprintf( _x( 'Customer removed "%1$s" (Product ID: #%2$d) via the My Account page.', 'used in order note', 'woocommerce-subscriptions' ), wcs_get_line_item_name( $line_item ), $product_id ) );
// translators: placeholders are 1$: item name, and, 2$: opening and, 3$: closing link tags
wc_add_notice( sprintf( __( 'You have successfully removed "%1$s" from your subscription. %2$sUndo?%3$s', 'woocommerce-subscriptions' ), $line_item['name'], '<a href="' . esc_url( self::get_undo_remove_url( $subscription->id, $item_id, $subscription->get_view_order_url() ) ) . '" >', '</a>' ) );
}
}
$subscription->calculate_totals();
wp_safe_redirect( $subscription->get_view_order_url() );
exit;
}
}
/**
* Validate the incoming request to either remove an item or add and item back to a subscription that was previously removed.
* Add an descriptive notice to the page whether or not the request was validated or not.
*
* @since 2.0
* @param WC_Subscription $subscription
* @param int $order_item_id
* @param bool $undo_request bool
* @return bool
*/
private static function validate_remove_items_request( $subscription, $order_item_id, $undo_request = false ) {
$subscription_items = $subscription->get_items();
$response = false;
if ( ! wp_verify_nonce( $_GET['_wpnonce'], $_GET['subscription_id'] ) ) {
wc_add_notice( __( 'Security error. Please contact us if you need assistance.', 'woocommerce-subscriptions' ), 'error' );
} elseif ( ! current_user_can( 'edit_shop_subscription_line_items', $subscription->id ) ) {
wc_add_notice( __( 'You cannot modify a subscription that does not belong to you.', 'woocommerce-subscriptions' ), 'error' );
} elseif ( ! $undo_request && ! isset( $subscription_items[ $order_item_id ] ) ) { // only need to validate the order item id when removing
wc_add_notice( __( 'You cannot remove an item that does not exist. ', 'woocommerce-subscriptions' ), 'error' );
} elseif ( ! $subscription->payment_method_supports( 'subscription_amount_changes' ) ) {
wc_add_notice( __( 'The item was not removed because this Subscription\'s payment method does not support removing an item.', 'woocommerce-subscriptions' ) );
} else {
$response = true;
}
return $response;
}
}
WCS_Remove_Item::init();