|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
/** |
|
3
|
|
|
* WooCommerce API Coupons Class |
|
4
|
|
|
* |
|
5
|
|
|
* Handles requests to the /coupons endpoint |
|
6
|
|
|
* |
|
7
|
|
|
* @author WooThemes |
|
8
|
|
|
* @category API |
|
9
|
|
|
* @package WooCommerce/API |
|
10
|
|
|
* @since 2.1 |
|
11
|
|
|
* @version 2.1 |
|
12
|
|
|
*/ |
|
13
|
|
|
|
|
14
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
|
15
|
|
|
exit; // Exit if accessed directly |
|
16
|
|
|
} |
|
17
|
|
|
|
|
18
|
|
|
class WC_API_Coupons extends WC_API_Resource { |
|
19
|
|
|
|
|
20
|
|
|
/** @var string $base the route base */ |
|
21
|
|
|
protected $base = '/coupons'; |
|
22
|
|
|
|
|
23
|
|
|
/** |
|
24
|
|
|
* Register the routes for this class |
|
25
|
|
|
* |
|
26
|
|
|
* GET /coupons |
|
27
|
|
|
* GET /coupons/count |
|
28
|
|
|
* GET /coupons/<id> |
|
29
|
|
|
* |
|
30
|
|
|
* @since 2.1 |
|
31
|
|
|
* @param array $routes |
|
32
|
|
|
* @return array |
|
33
|
|
|
*/ |
|
34
|
|
|
public function register_routes( $routes ) { |
|
35
|
|
|
|
|
36
|
|
|
# GET /coupons |
|
37
|
|
|
$routes[ $this->base ] = array( |
|
38
|
|
|
array( array( $this, 'get_coupons' ), WC_API_Server::READABLE ), |
|
39
|
|
|
); |
|
40
|
|
|
|
|
41
|
|
|
# GET /coupons/count |
|
42
|
|
|
$routes[ $this->base . '/count'] = array( |
|
43
|
|
|
array( array( $this, 'get_coupons_count' ), WC_API_Server::READABLE ), |
|
44
|
|
|
); |
|
45
|
|
|
|
|
46
|
|
|
# GET /coupons/<id> |
|
47
|
|
|
$routes[ $this->base . '/(?P<id>\d+)' ] = array( |
|
48
|
|
|
array( array( $this, 'get_coupon' ), WC_API_Server::READABLE ), |
|
49
|
|
|
); |
|
50
|
|
|
|
|
51
|
|
|
# GET /coupons/code/<code>, note that coupon codes can contain spaces, dashes and underscores |
|
52
|
|
|
$routes[ $this->base . '/code/(?P<code>\w[\w\s\-]*)' ] = array( |
|
53
|
|
|
array( array( $this, 'get_coupon_by_code' ), WC_API_Server::READABLE ), |
|
54
|
|
|
); |
|
55
|
|
|
|
|
56
|
|
|
return $routes; |
|
57
|
|
|
} |
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* Get all coupons |
|
61
|
|
|
* |
|
62
|
|
|
* @since 2.1 |
|
63
|
|
|
* @param string $fields |
|
64
|
|
|
* @param array $filter |
|
65
|
|
|
* @param int $page |
|
66
|
|
|
* @return array |
|
67
|
|
|
*/ |
|
68
|
|
|
public function get_coupons( $fields = null, $filter = array(), $page = 1 ) { |
|
69
|
|
|
|
|
70
|
|
|
$filter['page'] = $page; |
|
71
|
|
|
|
|
72
|
|
|
$query = $this->query_coupons( $filter ); |
|
73
|
|
|
|
|
74
|
|
|
$coupons = array(); |
|
75
|
|
|
|
|
76
|
|
|
foreach( $query->posts as $coupon_id ) { |
|
77
|
|
|
|
|
78
|
|
|
if ( ! $this->is_readable( $coupon_id ) ) |
|
79
|
|
|
continue; |
|
80
|
|
|
|
|
81
|
|
|
$coupons[] = current( $this->get_coupon( $coupon_id, $fields ) ); |
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
|
|
$this->server->add_pagination_headers( $query ); |
|
85
|
|
|
|
|
86
|
|
|
return array( 'coupons' => $coupons ); |
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
|
|
/** |
|
90
|
|
|
* Get the coupon for the given ID |
|
91
|
|
|
* |
|
92
|
|
|
* @since 2.1 |
|
93
|
|
|
* @param int $id the coupon ID |
|
94
|
|
|
* @param string $fields fields to include in response |
|
95
|
|
|
* @return array|WP_Error |
|
96
|
|
|
*/ |
|
97
|
|
|
public function get_coupon( $id, $fields = null ) { |
|
98
|
|
|
global $wpdb; |
|
99
|
|
|
|
|
100
|
|
|
$id = $this->validate_request( $id, 'shop_coupon', 'read' ); |
|
101
|
|
|
|
|
102
|
|
|
if ( is_wp_error( $id ) ) |
|
103
|
|
|
return $id; |
|
104
|
|
|
|
|
105
|
|
|
// get the coupon code |
|
106
|
|
|
$code = $wpdb->get_var( $wpdb->prepare( "SELECT post_title FROM $wpdb->posts WHERE id = %s AND post_type = 'shop_coupon' AND post_status = 'publish'", $id ) ); |
|
107
|
|
|
|
|
108
|
|
|
if ( is_null( $code ) ) |
|
109
|
|
|
return new WP_Error( 'woocommerce_api_invalid_coupon_id', __( 'Invalid coupon ID', 'woocommerce' ), array( 'status' => 404 ) ); |
|
110
|
|
|
|
|
111
|
|
|
$coupon = new WC_Coupon( $code ); |
|
112
|
|
|
|
|
113
|
|
|
$coupon_post = get_post( $coupon->id ); |
|
114
|
|
|
|
|
115
|
|
|
$coupon_data = array( |
|
116
|
|
|
'id' => $coupon->id, |
|
117
|
|
|
'code' => $coupon->code, |
|
118
|
|
|
'type' => $coupon->type, |
|
119
|
|
|
'created_at' => $this->server->format_datetime( $coupon_post->post_date_gmt ), |
|
120
|
|
|
'updated_at' => $this->server->format_datetime( $coupon_post->post_modified_gmt ), |
|
121
|
|
|
'amount' => wc_format_decimal( $coupon->amount, 2 ), |
|
122
|
|
|
'individual_use' => ( 'yes' === $coupon->individual_use ), |
|
123
|
|
|
'product_ids' => array_map( 'absint', (array) $coupon->product_ids ), |
|
124
|
|
|
'exclude_product_ids' => array_map( 'absint', (array) $coupon->exclude_product_ids ), |
|
125
|
|
|
'usage_limit' => ( ! empty( $coupon->usage_limit ) ) ? $coupon->usage_limit : null, |
|
126
|
|
|
'usage_limit_per_user' => ( ! empty( $coupon->usage_limit_per_user ) ) ? $coupon->usage_limit_per_user : null, |
|
127
|
|
|
'limit_usage_to_x_items' => (int) $coupon->limit_usage_to_x_items, |
|
128
|
|
|
'usage_count' => (int) $coupon->usage_count, |
|
129
|
|
|
'expiry_date' => $this->server->format_datetime( $coupon->expiry_date ), |
|
130
|
|
|
'enable_free_shipping' => $coupon->enable_free_shipping(), |
|
131
|
|
|
'product_category_ids' => array_map( 'absint', (array) $coupon->product_categories ), |
|
132
|
|
|
'exclude_product_category_ids' => array_map( 'absint', (array) $coupon->exclude_product_categories ), |
|
133
|
|
|
'exclude_sale_items' => $coupon->exclude_sale_items(), |
|
134
|
|
|
'minimum_amount' => wc_format_decimal( $coupon->minimum_amount, 2 ), |
|
135
|
|
|
'customer_emails' => $coupon->customer_email, |
|
136
|
|
|
); |
|
137
|
|
|
|
|
138
|
|
|
return array( 'coupon' => apply_filters( 'woocommerce_api_coupon_response', $coupon_data, $coupon, $fields, $this->server ) ); |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
/** |
|
142
|
|
|
* Get the total number of coupons |
|
143
|
|
|
* |
|
144
|
|
|
* @since 2.1 |
|
145
|
|
|
* @param array $filter |
|
146
|
|
|
* @return array |
|
147
|
|
|
*/ |
|
148
|
|
View Code Duplication |
public function get_coupons_count( $filter = array() ) { |
|
|
|
|
|
|
149
|
|
|
|
|
150
|
|
|
$query = $this->query_coupons( $filter ); |
|
151
|
|
|
|
|
152
|
|
|
if ( ! current_user_can( 'read_private_shop_coupons' ) ) |
|
153
|
|
|
return new WP_Error( 'woocommerce_api_user_cannot_read_coupons_count', __( 'You do not have permission to read the coupons count', 'woocommerce' ), array( 'status' => 401 ) ); |
|
154
|
|
|
|
|
155
|
|
|
return array( 'count' => (int) $query->found_posts ); |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
/** |
|
159
|
|
|
* Get the coupon for the given code |
|
160
|
|
|
* |
|
161
|
|
|
* @since 2.1 |
|
162
|
|
|
* @param string $code the coupon code |
|
163
|
|
|
* @param string $fields fields to include in response |
|
164
|
|
|
* @return int|WP_Error |
|
165
|
|
|
*/ |
|
166
|
|
View Code Duplication |
public function get_coupon_by_code( $code, $fields = null ) { |
|
|
|
|
|
|
167
|
|
|
global $wpdb; |
|
168
|
|
|
|
|
169
|
|
|
$id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 1;", $code ) ); |
|
170
|
|
|
|
|
171
|
|
|
if ( is_null( $id ) ) |
|
172
|
|
|
return new WP_Error( 'woocommerce_api_invalid_coupon_code', __( 'Invalid coupon code', 'woocommerce' ), array( 'status' => 404 ) ); |
|
173
|
|
|
|
|
174
|
|
|
return $this->get_coupon( $id, $fields ); |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
/** |
|
178
|
|
|
* Create a coupon |
|
179
|
|
|
* |
|
180
|
|
|
* @TODO implement in 2.2 |
|
181
|
|
|
* @param array $data |
|
182
|
|
|
* @return array |
|
183
|
|
|
*/ |
|
184
|
|
|
public function create_coupon( $data ) { |
|
|
|
|
|
|
185
|
|
|
|
|
186
|
|
|
return array(); |
|
187
|
|
|
} |
|
188
|
|
|
|
|
189
|
|
|
/** |
|
190
|
|
|
* Edit a coupon |
|
191
|
|
|
* |
|
192
|
|
|
* @TODO implement in 2.2 |
|
193
|
|
|
* @param int $id the coupon ID |
|
194
|
|
|
* @param array $data |
|
195
|
|
|
* @return array |
|
196
|
|
|
*/ |
|
197
|
|
|
public function edit_coupon( $id, $data ) { |
|
|
|
|
|
|
198
|
|
|
|
|
199
|
|
|
$id = $this->validate_request( $id, 'shop_coupon', 'edit' ); |
|
200
|
|
|
|
|
201
|
|
|
if ( is_wp_error( $id ) ) |
|
202
|
|
|
return $id; |
|
203
|
|
|
|
|
204
|
|
|
return $this->get_coupon( $id ); |
|
205
|
|
|
} |
|
206
|
|
|
|
|
207
|
|
|
/** |
|
208
|
|
|
* Delete a coupon |
|
209
|
|
|
* |
|
210
|
|
|
* @TODO enable along with PUT/POST in 2.2 |
|
211
|
|
|
* @param int $id the coupon ID |
|
212
|
|
|
* @param bool $force true to permanently delete coupon, false to move to trash |
|
213
|
|
|
* @return array |
|
214
|
|
|
*/ |
|
215
|
|
|
public function delete_coupon( $id, $force = false ) { |
|
216
|
|
|
|
|
217
|
|
|
$id = $this->validate_request( $id, 'shop_coupon', 'delete' ); |
|
218
|
|
|
|
|
219
|
|
|
if ( is_wp_error( $id ) ) |
|
220
|
|
|
return $id; |
|
221
|
|
|
|
|
222
|
|
|
return $this->delete( $id, 'shop_coupon', ( 'true' === $force ) ); |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
/** |
|
226
|
|
|
* Helper method to get coupon post objects |
|
227
|
|
|
* |
|
228
|
|
|
* @since 2.1 |
|
229
|
|
|
* @param array $args request arguments for filtering query |
|
230
|
|
|
* @return WP_Query |
|
231
|
|
|
*/ |
|
232
|
|
|
private function query_coupons( $args ) { |
|
233
|
|
|
|
|
234
|
|
|
// set base query arguments |
|
235
|
|
|
$query_args = array( |
|
236
|
|
|
'fields' => 'ids', |
|
237
|
|
|
'post_type' => 'shop_coupon', |
|
238
|
|
|
'post_status' => 'publish', |
|
239
|
|
|
); |
|
240
|
|
|
|
|
241
|
|
|
$query_args = $this->merge_query_args( $query_args, $args ); |
|
242
|
|
|
|
|
243
|
|
|
return new WP_Query( $query_args ); |
|
244
|
|
|
} |
|
245
|
|
|
|
|
246
|
|
|
} |
|
247
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.