1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* REST API Customer Downloads controller |
4
|
|
|
* |
5
|
|
|
* Handles requests to the /customers/<customer_id>/downloads endpoint. |
6
|
|
|
* |
7
|
|
|
* @author WooThemes |
8
|
|
|
* @category API |
9
|
|
|
* @package WooCommerce/API |
10
|
|
|
* @since 2.6.0 |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
14
|
|
|
exit; |
15
|
|
|
} |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* REST API Customers controller class. |
19
|
|
|
* |
20
|
|
|
* @package WooCommerce/API |
21
|
|
|
* @extends WC_REST_Controller |
22
|
|
|
*/ |
23
|
|
|
class WC_REST_Customer_Downloads_Controller extends WC_REST_Controller { |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Endpoint namespace. |
27
|
|
|
* |
28
|
|
|
* @var string |
29
|
|
|
*/ |
30
|
|
|
protected $namespace = 'wc/v1'; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Route base. |
34
|
|
|
* |
35
|
|
|
* @var string |
36
|
|
|
*/ |
37
|
|
|
protected $rest_base = 'customers/(?P<customer_id>[\d]+)/downloads'; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Register the routes for customers. |
41
|
|
|
*/ |
42
|
|
View Code Duplication |
public function register_routes() { |
|
|
|
|
43
|
|
|
register_rest_route( $this->namespace, '/' . $this->rest_base, array( |
44
|
|
|
array( |
45
|
|
|
'methods' => WP_REST_Server::READABLE, |
46
|
|
|
'callback' => array( $this, 'get_items' ), |
47
|
|
|
'permission_callback' => array( $this, 'get_items_permissions_check' ), |
48
|
|
|
'args' => $this->get_collection_params(), |
49
|
|
|
), |
50
|
|
|
'schema' => array( $this, 'get_public_item_schema' ), |
51
|
|
|
) ); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Check whether a given request has permission to read customers. |
56
|
|
|
* |
57
|
|
|
* @param WP_REST_Request $request Full details about the request. |
58
|
|
|
* @return WP_Error|boolean |
59
|
|
|
*/ |
60
|
|
|
public function get_items_permissions_check( $request ) { |
61
|
|
|
$customer = get_user_by( 'id', (int) $request['customer_id'] ); |
62
|
|
|
|
63
|
|
|
if ( ! $customer ) { |
64
|
|
|
return new WP_Error( "woocommerce_rest_customer_invalid", __( "Resource doesn't exist.", 'woocommerce' ), array( 'status' => 404 ) ); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
if ( ! wc_rest_check_user_permissions( 'read', $customer->id ) ) { |
68
|
|
|
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
return true; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* Get all customer downloads. |
76
|
|
|
* |
77
|
|
|
* @param WP_REST_Request $request |
78
|
|
|
* @return array |
79
|
|
|
*/ |
80
|
|
|
public function get_items( $request ) { |
81
|
|
|
$downloads = wc_get_customer_available_downloads( (int) $request['customer_id'] ); |
82
|
|
|
|
83
|
|
|
$data = array(); |
84
|
|
|
foreach ( $downloads as $download_data ) { |
85
|
|
|
$download = $this->prepare_item_for_response( (object) $download_data, $request ); |
86
|
|
|
$download = $this->prepare_response_for_collection( $download ); |
87
|
|
|
$data[] = $download; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
return rest_ensure_response( $data ); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Prepare a single download output for response. |
95
|
|
|
* |
96
|
|
|
* @param stdObject $download Download object. |
97
|
|
|
* @param WP_REST_Request $request Request object. |
98
|
|
|
* @return WP_REST_Response $response Response data. |
99
|
|
|
*/ |
100
|
|
|
public function prepare_item_for_response( $download, $request ) { |
101
|
|
|
$data = (array) $download; |
102
|
|
|
$data['access_expires'] = $data['access_expires'] ? wc_rest_prepare_date_response( $data['access_expires'] ) : 'never'; |
103
|
|
|
$data['downloads_remaining'] = '' === $data['downloads_remaining'] ? 'unlimited' : $data['downloads_remaining']; |
104
|
|
|
|
105
|
|
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view'; |
106
|
|
|
$data = $this->add_additional_fields_to_object( $data, $request ); |
107
|
|
|
$data = $this->filter_response_by_context( $data, $context ); |
108
|
|
|
|
109
|
|
|
// Wrap the data in a response object. |
110
|
|
|
$response = rest_ensure_response( $data ); |
111
|
|
|
|
112
|
|
|
$response->add_links( $this->prepare_links( $download, $request ) ); |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Filter customer download data returned from the REST API. |
116
|
|
|
* |
117
|
|
|
* @param WP_REST_Response $response The response object. |
118
|
|
|
* @param stdObject $download Download object used to create response. |
119
|
|
|
* @param WP_REST_Request $request Request object. |
120
|
|
|
*/ |
121
|
|
|
return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request ); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Prepare links for the request. |
126
|
|
|
* |
127
|
|
|
* @param stdClass $download Download object. |
128
|
|
|
* @param WP_REST_Request $request Request object. |
129
|
|
|
* @return array Links for the given customer download. |
130
|
|
|
*/ |
131
|
|
|
protected function prepare_links( $download, $request ) { |
132
|
|
|
$base = str_replace( '(?P<customer_id>[\d]+)', $request['customer_id'], $this->rest_base ); |
133
|
|
|
$links = array( |
134
|
|
|
'collection' => array( |
135
|
|
|
'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ), |
136
|
|
|
), |
137
|
|
|
'product' => array( |
138
|
|
|
'href' => rest_url( sprintf( '/%s/products/%d', $this->namespace, $download->product_id ) ), |
139
|
|
|
), |
140
|
|
|
'order' => array( |
141
|
|
|
'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $download->order_id ) ), |
142
|
|
|
), |
143
|
|
|
); |
144
|
|
|
|
145
|
|
|
return $links; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Get the Customer Download's schema, conforming to JSON Schema. |
150
|
|
|
* |
151
|
|
|
* @return array |
152
|
|
|
*/ |
153
|
|
View Code Duplication |
public function get_item_schema() { |
|
|
|
|
154
|
|
|
$schema = array( |
155
|
|
|
'$schema' => 'http://json-schema.org/draft-04/schema#', |
156
|
|
|
'title' => 'customer_download', |
157
|
|
|
'type' => 'object', |
158
|
|
|
'properties' => array( |
159
|
|
|
'download_url' => array( |
160
|
|
|
'description' => __( 'Download file URL.', 'woocommerce' ), |
161
|
|
|
'type' => 'string', |
162
|
|
|
'context' => array( 'view' ), |
163
|
|
|
'readonly' => true, |
164
|
|
|
), |
165
|
|
|
'download_id' => array( |
166
|
|
|
'description' => __( 'Download ID (MD5).', 'woocommerce' ), |
167
|
|
|
'type' => 'string', |
168
|
|
|
'context' => array( 'view' ), |
169
|
|
|
'readonly' => true, |
170
|
|
|
), |
171
|
|
|
'product_id' => array( |
172
|
|
|
'description' => __( 'Downloadable product ID.', 'woocommerce' ), |
173
|
|
|
'type' => 'integer', |
174
|
|
|
'context' => array( 'view' ), |
175
|
|
|
'readonly' => true, |
176
|
|
|
), |
177
|
|
|
'download_name' => array( |
178
|
|
|
'description' => __( 'Downloadable file name.', 'woocommerce' ), |
179
|
|
|
'type' => 'string', |
180
|
|
|
'context' => array( 'view' ), |
181
|
|
|
'readonly' => true, |
182
|
|
|
), |
183
|
|
|
'order_id' => array( |
184
|
|
|
'description' => __( 'Order ID.', 'woocommerce' ), |
185
|
|
|
'type' => 'integer', |
186
|
|
|
'context' => array( 'view' ), |
187
|
|
|
'readonly' => true, |
188
|
|
|
), |
189
|
|
|
'order_key' => array( |
190
|
|
|
'description' => __( 'Order key.', 'woocommerce' ), |
191
|
|
|
'type' => 'string', |
192
|
|
|
'context' => array( 'view' ), |
193
|
|
|
'readonly' => true, |
194
|
|
|
), |
195
|
|
|
'downloads_remaining' => array( |
196
|
|
|
'description' => __( 'Amount of downloads remaining.', 'woocommerce' ), |
197
|
|
|
'type' => 'string', |
198
|
|
|
'context' => array( 'view' ), |
199
|
|
|
'readonly' => true, |
200
|
|
|
), |
201
|
|
|
'access_expires' => array( |
202
|
|
|
'description' => __( "The date when the download access expires, in the site's timezone.", 'woocommerce' ), |
203
|
|
|
'type' => 'string', |
204
|
|
|
'context' => array( 'view' ), |
205
|
|
|
'readonly' => true, |
206
|
|
|
), |
207
|
|
|
'file' => array( |
208
|
|
|
'description' => __( 'File details.', 'woocommerce' ), |
209
|
|
|
'type' => 'array', |
210
|
|
|
'context' => array( 'view' ), |
211
|
|
|
'readonly' => true, |
212
|
|
|
'properties' => array( |
213
|
|
|
'name' => array( |
214
|
|
|
'description' => __( 'File name.', 'woocommerce' ), |
215
|
|
|
'type' => 'string', |
216
|
|
|
'context' => array( 'view' ), |
217
|
|
|
'readonly' => true, |
218
|
|
|
), |
219
|
|
|
'file' => array( |
220
|
|
|
'description' => __( 'File URL.', 'woocommerce' ), |
221
|
|
|
'type' => 'string', |
222
|
|
|
'context' => array( 'view' ), |
223
|
|
|
'readonly' => true, |
224
|
|
|
), |
225
|
|
|
), |
226
|
|
|
), |
227
|
|
|
), |
228
|
|
|
); |
229
|
|
|
|
230
|
|
|
return $this->add_additional_fields_schema( $schema ); |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* Get the query params for collections. |
235
|
|
|
* |
236
|
|
|
* @return array |
237
|
|
|
*/ |
238
|
|
|
public function get_collection_params() { |
239
|
|
|
return array( |
240
|
|
|
'context' => $this->get_context_param( array( 'default' => 'view' ) ), |
241
|
|
|
); |
242
|
|
|
} |
243
|
|
|
} |
244
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.