|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
/** |
|
3
|
|
|
* WooCommerce API Customers Class |
|
4
|
|
|
* |
|
5
|
|
|
* Handles requests to the /customers 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_Customers extends WC_API_Resource { |
|
19
|
|
|
|
|
20
|
|
|
/** @var string $base the route base */ |
|
21
|
|
|
protected $base = '/customers'; |
|
22
|
|
|
|
|
23
|
|
|
/** @var string $created_at_min for date filtering */ |
|
24
|
|
|
private $created_at_min = null; |
|
25
|
|
|
|
|
26
|
|
|
/** @var string $created_at_max for date filtering */ |
|
27
|
|
|
private $created_at_max = null; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* Setup class, overridden to provide customer data to order response |
|
31
|
|
|
* |
|
32
|
|
|
* @since 2.1 |
|
33
|
|
|
* @param WC_API_Server $server |
|
34
|
|
|
* @return WC_API_Customers |
|
|
|
|
|
|
35
|
|
|
*/ |
|
36
|
|
View Code Duplication |
public function __construct( WC_API_Server $server ) { |
|
|
|
|
|
|
37
|
|
|
|
|
38
|
|
|
parent::__construct( $server ); |
|
39
|
|
|
|
|
40
|
|
|
// add customer data to order responses |
|
41
|
|
|
add_filter( 'woocommerce_api_order_response', array( $this, 'add_customer_data' ), 10, 2 ); |
|
42
|
|
|
|
|
43
|
|
|
// modify WP_User_Query to support created_at date filtering |
|
44
|
|
|
add_action( 'pre_user_query', array( $this, 'modify_user_query' ) ); |
|
45
|
|
|
} |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* Register the routes for this class |
|
49
|
|
|
* |
|
50
|
|
|
* GET /customers |
|
51
|
|
|
* GET /customers/count |
|
52
|
|
|
* GET /customers/<id> |
|
53
|
|
|
* GET /customers/<id>/orders |
|
54
|
|
|
* |
|
55
|
|
|
* @since 2.1 |
|
56
|
|
|
* @param array $routes |
|
57
|
|
|
* @return array |
|
58
|
|
|
*/ |
|
59
|
|
|
public function register_routes( $routes ) { |
|
60
|
|
|
|
|
61
|
|
|
# GET /customers |
|
62
|
|
|
$routes[ $this->base ] = array( |
|
63
|
|
|
array( array( $this, 'get_customers' ), WC_API_SERVER::READABLE ), |
|
64
|
|
|
); |
|
65
|
|
|
|
|
66
|
|
|
# GET /customers/count |
|
67
|
|
|
$routes[ $this->base . '/count'] = array( |
|
68
|
|
|
array( array( $this, 'get_customers_count' ), WC_API_SERVER::READABLE ), |
|
69
|
|
|
); |
|
70
|
|
|
|
|
71
|
|
|
# GET /customers/<id> |
|
72
|
|
|
$routes[ $this->base . '/(?P<id>\d+)' ] = array( |
|
73
|
|
|
array( array( $this, 'get_customer' ), WC_API_SERVER::READABLE ), |
|
74
|
|
|
); |
|
75
|
|
|
|
|
76
|
|
|
# GET /customers/<id>/orders |
|
77
|
|
|
$routes[ $this->base . '/(?P<id>\d+)/orders' ] = array( |
|
78
|
|
|
array( array( $this, 'get_customer_orders' ), WC_API_SERVER::READABLE ), |
|
79
|
|
|
); |
|
80
|
|
|
|
|
81
|
|
|
return $routes; |
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
|
|
/** |
|
85
|
|
|
* Get all customers |
|
86
|
|
|
* |
|
87
|
|
|
* @since 2.1 |
|
88
|
|
|
* @param array $fields |
|
89
|
|
|
* @param array $filter |
|
90
|
|
|
* @param int $page |
|
91
|
|
|
* @return array |
|
92
|
|
|
*/ |
|
93
|
|
|
public function get_customers( $fields = null, $filter = array(), $page = 1 ) { |
|
94
|
|
|
|
|
95
|
|
|
$filter['page'] = $page; |
|
96
|
|
|
|
|
97
|
|
|
$query = $this->query_customers( $filter ); |
|
98
|
|
|
|
|
99
|
|
|
$customers = array(); |
|
100
|
|
|
|
|
101
|
|
|
foreach( $query->get_results() as $user_id ) { |
|
102
|
|
|
|
|
103
|
|
|
if ( ! $this->is_readable( $user_id ) ) |
|
104
|
|
|
continue; |
|
105
|
|
|
|
|
106
|
|
|
$customers[] = current( $this->get_customer( $user_id, $fields ) ); |
|
|
|
|
|
|
107
|
|
|
} |
|
108
|
|
|
|
|
109
|
|
|
$this->server->add_pagination_headers( $query ); |
|
110
|
|
|
|
|
111
|
|
|
return array( 'customers' => $customers ); |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
/** |
|
115
|
|
|
* Get the customer for the given ID |
|
116
|
|
|
* |
|
117
|
|
|
* @since 2.1 |
|
118
|
|
|
* @param int $id the customer ID |
|
119
|
|
|
* @param string $fields |
|
120
|
|
|
* @return array |
|
121
|
|
|
*/ |
|
122
|
|
|
public function get_customer( $id, $fields = null ) { |
|
123
|
|
|
global $wpdb; |
|
124
|
|
|
|
|
125
|
|
|
$id = $this->validate_request( $id, 'customer', 'read' ); |
|
126
|
|
|
|
|
127
|
|
|
if ( is_wp_error( $id ) ) |
|
128
|
|
|
return $id; |
|
129
|
|
|
|
|
130
|
|
|
$customer = new WP_User( $id ); |
|
131
|
|
|
|
|
132
|
|
|
// get info about user's last order |
|
133
|
|
|
$last_order = $wpdb->get_row( "SELECT id, post_date_gmt |
|
134
|
|
|
FROM $wpdb->posts AS posts |
|
135
|
|
|
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id |
|
136
|
|
|
WHERE meta.meta_key = '_customer_user' |
|
137
|
|
|
AND meta.meta_value = {$customer->ID} |
|
138
|
|
|
AND posts.post_type = 'shop_order' |
|
139
|
|
|
AND posts.post_status IN ( '" . implode( "','", array_keys( wc_get_order_statuses() ) ) . "' ) |
|
140
|
|
|
" ); |
|
141
|
|
|
|
|
142
|
|
|
$customer_data = array( |
|
143
|
|
|
'id' => $customer->ID, |
|
144
|
|
|
'created_at' => $this->server->format_datetime( $customer->user_registered ), |
|
145
|
|
|
'email' => $customer->user_email, |
|
146
|
|
|
'first_name' => $customer->first_name, |
|
147
|
|
|
'last_name' => $customer->last_name, |
|
148
|
|
|
'username' => $customer->user_login, |
|
149
|
|
|
'last_order_id' => is_object( $last_order ) ? $last_order->id : null, |
|
150
|
|
|
'last_order_date' => is_object( $last_order ) ? $this->server->format_datetime( $last_order->post_date_gmt ) : null, |
|
151
|
|
|
'orders_count' => (int) $customer->_order_count, |
|
152
|
|
|
'total_spent' => wc_format_decimal( $customer->_money_spent, 2 ), |
|
153
|
|
|
'avatar_url' => $this->get_avatar_url( $customer->customer_email ), |
|
154
|
|
|
'billing_address' => array( |
|
155
|
|
|
'first_name' => $customer->billing_first_name, |
|
156
|
|
|
'last_name' => $customer->billing_last_name, |
|
157
|
|
|
'company' => $customer->billing_company, |
|
158
|
|
|
'address_1' => $customer->billing_address_1, |
|
159
|
|
|
'address_2' => $customer->billing_address_2, |
|
160
|
|
|
'city' => $customer->billing_city, |
|
161
|
|
|
'state' => $customer->billing_state, |
|
162
|
|
|
'postcode' => $customer->billing_postcode, |
|
163
|
|
|
'country' => $customer->billing_country, |
|
164
|
|
|
'email' => $customer->billing_email, |
|
165
|
|
|
'phone' => $customer->billing_phone, |
|
166
|
|
|
), |
|
167
|
|
|
'shipping_address' => array( |
|
168
|
|
|
'first_name' => $customer->shipping_first_name, |
|
169
|
|
|
'last_name' => $customer->shipping_last_name, |
|
170
|
|
|
'company' => $customer->shipping_company, |
|
171
|
|
|
'address_1' => $customer->shipping_address_1, |
|
172
|
|
|
'address_2' => $customer->shipping_address_2, |
|
173
|
|
|
'city' => $customer->shipping_city, |
|
174
|
|
|
'state' => $customer->shipping_state, |
|
175
|
|
|
'postcode' => $customer->shipping_postcode, |
|
176
|
|
|
'country' => $customer->shipping_country, |
|
177
|
|
|
), |
|
178
|
|
|
); |
|
179
|
|
|
|
|
180
|
|
|
return array( 'customer' => apply_filters( 'woocommerce_api_customer_response', $customer_data, $customer, $fields, $this->server ) ); |
|
181
|
|
|
} |
|
182
|
|
|
|
|
183
|
|
|
/** |
|
184
|
|
|
* Get the total number of customers |
|
185
|
|
|
* |
|
186
|
|
|
* @since 2.1 |
|
187
|
|
|
* @param array $filter |
|
188
|
|
|
* @return array |
|
189
|
|
|
*/ |
|
190
|
|
View Code Duplication |
public function get_customers_count( $filter = array() ) { |
|
|
|
|
|
|
191
|
|
|
|
|
192
|
|
|
$query = $this->query_customers( $filter ); |
|
193
|
|
|
|
|
194
|
|
|
if ( ! current_user_can( 'list_users' ) ) |
|
195
|
|
|
return new WP_Error( 'woocommerce_api_user_cannot_read_customers_count', __( 'You do not have permission to read the customers count', 'woocommerce' ), array( 'status' => 401 ) ); |
|
196
|
|
|
|
|
197
|
|
|
return array( 'count' => count( $query->get_results() ) ); |
|
198
|
|
|
} |
|
199
|
|
|
|
|
200
|
|
|
|
|
201
|
|
|
/** |
|
202
|
|
|
* Create a customer |
|
203
|
|
|
* |
|
204
|
|
|
* @TODO implement in 2.2 with woocommerce_create_new_customer() |
|
205
|
|
|
* @param array $data |
|
206
|
|
|
* @return array |
|
207
|
|
|
*/ |
|
208
|
|
|
public function create_customer( $data ) { |
|
|
|
|
|
|
209
|
|
|
|
|
210
|
|
|
if ( ! current_user_can( 'create_users' ) ) |
|
211
|
|
|
return new WP_Error( 'woocommerce_api_user_cannot_create_customer', __( 'You do not have permission to create this customer', 'woocommerce' ), array( 'status' => 401 ) ); |
|
212
|
|
|
|
|
213
|
|
|
return array(); |
|
214
|
|
|
} |
|
215
|
|
|
|
|
216
|
|
|
/** |
|
217
|
|
|
* Edit a customer |
|
218
|
|
|
* |
|
219
|
|
|
* @TODO implement in 2.2 |
|
220
|
|
|
* @param int $id the customer ID |
|
221
|
|
|
* @param array $data |
|
222
|
|
|
* @return array |
|
223
|
|
|
*/ |
|
224
|
|
View Code Duplication |
public function edit_customer( $id, $data ) { |
|
|
|
|
|
|
225
|
|
|
|
|
226
|
|
|
$id = $this->validate_request( $id, 'customer', 'edit' ); |
|
227
|
|
|
|
|
228
|
|
|
if ( ! is_wp_error( $id ) ) |
|
229
|
|
|
return $id; |
|
230
|
|
|
|
|
231
|
|
|
return $this->get_customer( $id ); |
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
/** |
|
235
|
|
|
* Delete a customer |
|
236
|
|
|
* |
|
237
|
|
|
* @TODO enable along with PUT/POST in 2.2 |
|
238
|
|
|
* @param int $id the customer ID |
|
239
|
|
|
* @return array |
|
240
|
|
|
*/ |
|
241
|
|
View Code Duplication |
public function delete_customer( $id ) { |
|
|
|
|
|
|
242
|
|
|
|
|
243
|
|
|
$id = $this->validate_request( $id, 'customer', 'delete' ); |
|
244
|
|
|
|
|
245
|
|
|
if ( ! is_wp_error( $id ) ) |
|
246
|
|
|
return $id; |
|
247
|
|
|
|
|
248
|
|
|
return $this->delete( $id, 'customer' ); |
|
249
|
|
|
} |
|
250
|
|
|
|
|
251
|
|
|
/** |
|
252
|
|
|
* Get the orders for a customer |
|
253
|
|
|
* |
|
254
|
|
|
* @since 2.1 |
|
255
|
|
|
* @param int $id the customer ID |
|
256
|
|
|
* @param string $fields fields to include in response |
|
257
|
|
|
* @return array |
|
258
|
|
|
*/ |
|
259
|
|
View Code Duplication |
public function get_customer_orders( $id, $fields = null ) { |
|
|
|
|
|
|
260
|
|
|
global $wpdb; |
|
261
|
|
|
|
|
262
|
|
|
$id = $this->validate_request( $id, 'customer', 'read' ); |
|
263
|
|
|
|
|
264
|
|
|
if ( is_wp_error( $id ) ) |
|
265
|
|
|
return $id; |
|
266
|
|
|
|
|
267
|
|
|
$order_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id |
|
268
|
|
|
FROM $wpdb->posts AS posts |
|
269
|
|
|
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id |
|
270
|
|
|
WHERE meta.meta_key = '_customer_user' |
|
271
|
|
|
AND meta.meta_value = '%s' |
|
272
|
|
|
AND posts.post_type = 'shop_order' |
|
273
|
|
|
AND posts.post_status = IN ( '" . implode( "','", array_keys( wc_get_order_statuses() ) ) . "' ) |
|
274
|
|
|
", $id ) ); |
|
275
|
|
|
|
|
276
|
|
|
if ( empty( $order_ids ) ) |
|
277
|
|
|
return array( 'orders' => array() ); |
|
278
|
|
|
|
|
279
|
|
|
$orders = array(); |
|
280
|
|
|
|
|
281
|
|
|
foreach ( $order_ids as $order_id ) { |
|
282
|
|
|
$orders[] = current( WC()->api->WC_API_Orders->get_order( $order_id, $fields ) ); |
|
283
|
|
|
} |
|
284
|
|
|
|
|
285
|
|
|
return array( 'orders' => apply_filters( 'woocommerce_api_customer_orders_response', $orders, $id, $fields, $order_ids, $this->server ) ); |
|
286
|
|
|
} |
|
287
|
|
|
|
|
288
|
|
|
/** |
|
289
|
|
|
* Helper method to get customer user objects |
|
290
|
|
|
* |
|
291
|
|
|
* Note that WP_User_Query does not have built-in pagination so limit & offset are used to provide limited |
|
292
|
|
|
* pagination support |
|
293
|
|
|
* |
|
294
|
|
|
* @since 2.1 |
|
295
|
|
|
* @param array $args request arguments for filtering query |
|
296
|
|
|
* @return WP_User_Query |
|
297
|
|
|
*/ |
|
298
|
|
|
private function query_customers( $args = array() ) { |
|
299
|
|
|
|
|
300
|
|
|
// default users per page |
|
301
|
|
|
$users_per_page = get_option( 'posts_per_page' ); |
|
302
|
|
|
|
|
303
|
|
|
// set base query arguments |
|
304
|
|
|
$query_args = array( |
|
305
|
|
|
'fields' => 'ID', |
|
306
|
|
|
'role' => 'customer', |
|
307
|
|
|
'orderby' => 'registered', |
|
308
|
|
|
'number' => $users_per_page, |
|
309
|
|
|
); |
|
310
|
|
|
|
|
311
|
|
|
// search |
|
312
|
|
|
if ( ! empty( $args['q'] ) ) { |
|
313
|
|
|
$query_args['search'] = $args['q']; |
|
314
|
|
|
} |
|
315
|
|
|
|
|
316
|
|
|
// limit number of users returned |
|
317
|
|
View Code Duplication |
if ( ! empty( $args['limit'] ) ) { |
|
|
|
|
|
|
318
|
|
|
|
|
319
|
|
|
$query_args['number'] = absint( $args['limit'] ); |
|
320
|
|
|
|
|
321
|
|
|
$users_per_page = absint( $args['limit'] ); |
|
322
|
|
|
} |
|
323
|
|
|
|
|
324
|
|
|
// page |
|
325
|
|
|
$page = ( isset( $args['page'] ) ) ? absint( $args['page'] ) : 1; |
|
326
|
|
|
|
|
327
|
|
|
// offset |
|
328
|
|
View Code Duplication |
if ( ! empty( $args['offset'] ) ) { |
|
|
|
|
|
|
329
|
|
|
$query_args['offset'] = absint( $args['offset'] ); |
|
330
|
|
|
} else { |
|
331
|
|
|
$query_args['offset'] = $users_per_page * ( $page - 1 ); |
|
332
|
|
|
} |
|
333
|
|
|
|
|
334
|
|
|
// created date |
|
335
|
|
|
if ( ! empty( $args['created_at_min'] ) ) { |
|
336
|
|
|
$this->created_at_min = $this->server->parse_datetime( $args['created_at_min'] ); |
|
337
|
|
|
} |
|
338
|
|
|
|
|
339
|
|
|
if ( ! empty( $args['created_at_max'] ) ) { |
|
340
|
|
|
$this->created_at_max = $this->server->parse_datetime( $args['created_at_max'] ); |
|
341
|
|
|
} |
|
342
|
|
|
|
|
343
|
|
|
$query = new WP_User_Query( $query_args ); |
|
344
|
|
|
|
|
345
|
|
|
// helper members for pagination headers |
|
346
|
|
|
$query->total_pages = ceil( $query->get_total() / $users_per_page ); |
|
347
|
|
|
$query->page = $page; |
|
348
|
|
|
|
|
349
|
|
|
return $query; |
|
350
|
|
|
} |
|
351
|
|
|
|
|
352
|
|
|
/** |
|
353
|
|
|
* Add customer data to orders |
|
354
|
|
|
* |
|
355
|
|
|
* @since 2.1 |
|
356
|
|
|
* @param $order_data |
|
357
|
|
|
* @param $order |
|
358
|
|
|
* @return array |
|
359
|
|
|
*/ |
|
360
|
|
View Code Duplication |
public function add_customer_data( $order_data, $order ) { |
|
|
|
|
|
|
361
|
|
|
|
|
362
|
|
|
if ( 0 == $order->customer_user ) { |
|
363
|
|
|
|
|
364
|
|
|
// add customer data from order |
|
365
|
|
|
$order_data['customer'] = array( |
|
366
|
|
|
'id' => 0, |
|
367
|
|
|
'email' => $order->billing_email, |
|
368
|
|
|
'first_name' => $order->billing_first_name, |
|
369
|
|
|
'last_name' => $order->billing_last_name, |
|
370
|
|
|
'billing_address' => array( |
|
371
|
|
|
'first_name' => $order->billing_first_name, |
|
372
|
|
|
'last_name' => $order->billing_last_name, |
|
373
|
|
|
'company' => $order->billing_company, |
|
374
|
|
|
'address_1' => $order->billing_address_1, |
|
375
|
|
|
'address_2' => $order->billing_address_2, |
|
376
|
|
|
'city' => $order->billing_city, |
|
377
|
|
|
'state' => $order->billing_state, |
|
378
|
|
|
'postcode' => $order->billing_postcode, |
|
379
|
|
|
'country' => $order->billing_country, |
|
380
|
|
|
'email' => $order->billing_email, |
|
381
|
|
|
'phone' => $order->billing_phone, |
|
382
|
|
|
), |
|
383
|
|
|
'shipping_address' => array( |
|
384
|
|
|
'first_name' => $order->shipping_first_name, |
|
385
|
|
|
'last_name' => $order->shipping_last_name, |
|
386
|
|
|
'company' => $order->shipping_company, |
|
387
|
|
|
'address_1' => $order->shipping_address_1, |
|
388
|
|
|
'address_2' => $order->shipping_address_2, |
|
389
|
|
|
'city' => $order->shipping_city, |
|
390
|
|
|
'state' => $order->shipping_state, |
|
391
|
|
|
'postcode' => $order->shipping_postcode, |
|
392
|
|
|
'country' => $order->shipping_country, |
|
393
|
|
|
), |
|
394
|
|
|
); |
|
395
|
|
|
|
|
396
|
|
|
} else { |
|
397
|
|
|
|
|
398
|
|
|
$order_data['customer'] = current( $this->get_customer( $order->customer_user ) ); |
|
399
|
|
|
} |
|
400
|
|
|
|
|
401
|
|
|
return $order_data; |
|
402
|
|
|
} |
|
403
|
|
|
|
|
404
|
|
|
/** |
|
405
|
|
|
* Modify the WP_User_Query to support filtering on the date the customer was created |
|
406
|
|
|
* |
|
407
|
|
|
* @since 2.1 |
|
408
|
|
|
* @param WP_User_Query $query |
|
409
|
|
|
*/ |
|
410
|
|
View Code Duplication |
public function modify_user_query( $query ) { |
|
|
|
|
|
|
411
|
|
|
|
|
412
|
|
|
if ( $this->created_at_min ) |
|
413
|
|
|
$query->query_where .= sprintf( " AND user_registered >= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%h:%%i:%%s' )", esc_sql( $this->created_at_min ) ); |
|
414
|
|
|
|
|
415
|
|
|
if ( $this->created_at_max ) |
|
416
|
|
|
$query->query_where .= sprintf( " AND user_registered <= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%h:%%i:%%s' )", esc_sql( $this->created_at_max ) ); |
|
417
|
|
|
} |
|
418
|
|
|
|
|
419
|
|
|
/** |
|
420
|
|
|
* Wrapper for @see get_avatar() which doesn't simply return |
|
421
|
|
|
* the URL so we need to pluck it from the HTML img tag |
|
422
|
|
|
* |
|
423
|
|
|
* @since 2.1 |
|
424
|
|
|
* @param string $email the customer's email |
|
425
|
|
|
* @return string the URL to the customer's avatar |
|
426
|
|
|
*/ |
|
427
|
|
View Code Duplication |
private function get_avatar_url( $email ) { |
|
|
|
|
|
|
428
|
|
|
|
|
429
|
|
|
$avatar_html = get_avatar( $email ); |
|
430
|
|
|
|
|
431
|
|
|
// Get the URL of the avatar from the provided HTML |
|
432
|
|
|
preg_match( '/src=["|\'](.+)[\&|"|\']/U', $avatar_html, $matches ); |
|
433
|
|
|
|
|
434
|
|
|
if ( isset( $matches[1] ) && ! empty( $matches[1] ) ) { |
|
435
|
|
|
return esc_url_raw( $matches[1] ); |
|
436
|
|
|
} |
|
437
|
|
|
|
|
438
|
|
|
return null; |
|
439
|
|
|
} |
|
440
|
|
|
|
|
441
|
|
|
/** |
|
442
|
|
|
* Validate the request by checking: |
|
443
|
|
|
* |
|
444
|
|
|
* 1) the ID is a valid integer |
|
445
|
|
|
* 2) the ID returns a valid WP_User |
|
446
|
|
|
* 3) the current user has the proper permissions |
|
447
|
|
|
* |
|
448
|
|
|
* @since 2.1 |
|
449
|
|
|
* @see WC_API_Resource::validate_request() |
|
450
|
|
|
* @param string|int $id the customer ID |
|
451
|
|
|
* @param string $type the request type, unused because this method overrides the parent class |
|
452
|
|
|
* @param string $context the context of the request, either `read`, `edit` or `delete` |
|
453
|
|
|
* @return int|WP_Error valid user ID or WP_Error if any of the checks fails |
|
454
|
|
|
*/ |
|
455
|
|
|
protected function validate_request( $id, $type, $context ) { |
|
456
|
|
|
|
|
457
|
|
|
$id = absint( $id ); |
|
458
|
|
|
|
|
459
|
|
|
// validate ID |
|
460
|
|
|
if ( empty( $id ) ) |
|
461
|
|
|
return new WP_Error( 'woocommerce_api_invalid_customer_id', __( 'Invalid customer ID', 'woocommerce' ), array( 'status' => 404 ) ); |
|
462
|
|
|
|
|
463
|
|
|
// non-existent IDs return a valid WP_User object with the user ID = 0 |
|
464
|
|
|
$customer = new WP_User( $id ); |
|
465
|
|
|
|
|
466
|
|
|
if ( 0 === $customer->ID ) |
|
467
|
|
|
return new WP_Error( 'woocommerce_api_invalid_customer', __( 'Invalid customer', 'woocommerce' ), array( 'status' => 404 ) ); |
|
468
|
|
|
|
|
469
|
|
|
// validate permissions |
|
470
|
|
|
switch ( $context ) { |
|
471
|
|
|
|
|
472
|
|
|
case 'read': |
|
473
|
|
|
if ( ! current_user_can( 'list_users' ) ) |
|
474
|
|
|
return new WP_Error( 'woocommerce_api_user_cannot_read_customer', __( 'You do not have permission to read this customer', 'woocommerce' ), array( 'status' => 401 ) ); |
|
475
|
|
|
break; |
|
476
|
|
|
|
|
477
|
|
|
case 'edit': |
|
478
|
|
|
if ( ! current_user_can( 'edit_users' ) ) |
|
479
|
|
|
return new WP_Error( 'woocommerce_api_user_cannot_edit_customer', __( 'You do not have permission to edit this customer', 'woocommerce' ), array( 'status' => 401 ) ); |
|
480
|
|
|
break; |
|
481
|
|
|
|
|
482
|
|
|
case 'delete': |
|
483
|
|
|
if ( ! current_user_can( 'delete_users' ) ) |
|
484
|
|
|
return new WP_Error( 'woocommerce_api_user_cannot_delete_customer', __( 'You do not have permission to delete this customer', 'woocommerce' ), array( 'status' => 401 ) ); |
|
485
|
|
|
break; |
|
486
|
|
|
} |
|
487
|
|
|
|
|
488
|
|
|
return $id; |
|
489
|
|
|
} |
|
490
|
|
|
|
|
491
|
|
|
/** |
|
492
|
|
|
* Check if the current user can read users |
|
493
|
|
|
* |
|
494
|
|
|
* @since 2.1 |
|
495
|
|
|
* @see WC_API_Resource::is_readable() |
|
496
|
|
|
* @param int|WP_Post $post unused |
|
497
|
|
|
* @return bool true if the current user can read users, false otherwise |
|
498
|
|
|
*/ |
|
499
|
|
|
protected function is_readable( $post ) { |
|
500
|
|
|
|
|
501
|
|
|
return current_user_can( 'list_users' ); |
|
502
|
|
|
} |
|
503
|
|
|
|
|
504
|
|
|
} |
|
505
|
|
|
|
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.