This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * WooCommerce REST Functions |
||
4 | * |
||
5 | * Functions for REST specific things. |
||
6 | * |
||
7 | * @author WooThemes |
||
8 | * @category Core |
||
9 | * @package WooCommerce/Functions |
||
10 | * @version 2.6.0 |
||
11 | */ |
||
12 | |||
13 | if ( ! defined( 'ABSPATH' ) ) { |
||
14 | exit; |
||
15 | } |
||
16 | |||
17 | /** |
||
18 | * Parses and formats a MySQL datetime (Y-m-d H:i:s) for ISO8601/RFC3339. |
||
19 | * |
||
20 | * Requered WP 4.4 or later. |
||
21 | * See https://developer.wordpress.org/reference/functions/mysql_to_rfc3339/ |
||
22 | * |
||
23 | * @since 2.6.0 |
||
24 | * @param string $date_gmt |
||
25 | * @param string|null $date |
||
26 | * @return string|null ISO8601/RFC3339 formatted datetime. |
||
27 | */ |
||
28 | function wc_rest_prepare_date_response( $date_gmt, $date = null ) { |
||
29 | // Check if mysql_to_rfc3339 exists first! |
||
30 | if ( ! function_exists( 'mysql_to_rfc3339' ) ) { |
||
31 | return null; |
||
32 | } |
||
33 | |||
34 | // Use the date if passed. |
||
35 | if ( isset( $date ) ) { |
||
36 | return mysql_to_rfc3339( $date ); |
||
37 | } |
||
38 | |||
39 | // Return null if $date_gmt is empty/zeros. |
||
40 | if ( '0000-00-00 00:00:00' === $date_gmt ) { |
||
41 | return null; |
||
42 | } |
||
43 | |||
44 | // Return the formatted datetime. |
||
45 | return mysql_to_rfc3339( $date_gmt ); |
||
46 | } |
||
47 | |||
48 | /** |
||
49 | * Upload image from URL. |
||
50 | * |
||
51 | * @since 2.6.0 |
||
52 | * @param string $image_url |
||
53 | * @return array|WP_Error Attachment data or error message. |
||
54 | */ |
||
55 | function wc_rest_upload_image_from_url( $image_url ) { |
||
56 | $file_name = basename( current( explode( '?', $image_url ) ) ); |
||
57 | $wp_filetype = wp_check_filetype( $file_name, null ); |
||
58 | $parsed_url = @parse_url( $image_url ); |
||
59 | |||
60 | // Check parsed URL. |
||
61 | View Code Duplication | if ( ! $parsed_url || ! is_array( $parsed_url ) ) { |
|
0 ignored issues
–
show
|
|||
62 | return new WP_Error( 'woocommerce_rest_invalid_image_url', sprintf( __( 'Invalid URL %s.', 'woocommerce' ), $image_url ), array( 'status' => 400 ) ); |
||
63 | } |
||
64 | |||
65 | // Ensure url is valid. |
||
66 | $image_url = esc_url_raw( $image_url ); |
||
67 | |||
68 | // Get the file. |
||
69 | $response = wp_safe_remote_get( $image_url, array( |
||
70 | 'timeout' => 10 |
||
71 | ) ); |
||
72 | |||
73 | View Code Duplication | if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
74 | return new WP_Error( 'woocommerce_rest_invalid_remote_image_url', sprintf( __( 'Error getting remote image %s.', 'woocommerce' ), $image_url ), array( 'status' => 400 ) ); |
||
75 | } |
||
76 | |||
77 | // Ensure we have a file name and type. |
||
78 | View Code Duplication | if ( ! $wp_filetype['type'] ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
79 | $headers = wp_remote_retrieve_headers( $response ); |
||
80 | if ( isset( $headers['content-disposition'] ) && strstr( $headers['content-disposition'], 'filename=' ) ) { |
||
81 | $disposition = end( explode( 'filename=', $headers['content-disposition'] ) ); |
||
82 | $disposition = sanitize_file_name( $disposition ); |
||
83 | $file_name = $disposition; |
||
84 | } elseif ( isset( $headers['content-type'] ) && strstr( $headers['content-type'], 'image/' ) ) { |
||
85 | $file_name = 'image.' . str_replace( 'image/', '', $headers['content-type'] ); |
||
86 | } |
||
87 | unset( $headers ); |
||
88 | } |
||
89 | |||
90 | // Upload the file. |
||
91 | $upload = wp_upload_bits( $file_name, '', wp_remote_retrieve_body( $response ) ); |
||
92 | |||
93 | if ( $upload['error'] ) { |
||
94 | return new WP_Error( 'woocommerce_rest_image_upload_error', $upload['error'], array( 'status' => 400 ) ); |
||
95 | } |
||
96 | |||
97 | // Get filesize. |
||
98 | $filesize = filesize( $upload['file'] ); |
||
99 | |||
100 | if ( 0 == $filesize ) { |
||
101 | @unlink( $upload['file'] ); |
||
102 | unset( $upload ); |
||
103 | |||
104 | return new WP_Error( 'woocommerce_rest_image_upload_file_error', __( 'Zero size file downloaded.', 'woocommerce' ), array( 'status' => 400 ) ); |
||
105 | } |
||
106 | |||
107 | do_action( 'woocommerce_rest_api_uploaded_image_from_url', $upload, $image_url ); |
||
108 | |||
109 | return $upload; |
||
110 | } |
||
111 | |||
112 | /** |
||
113 | * Set uploaded image as attachment. |
||
114 | * |
||
115 | * @since 2.6.0 |
||
116 | * @param array $upload Upload information from wp_upload_bits. |
||
117 | * @param int $id Post ID. Default to 0. |
||
118 | * @return int Attachment ID |
||
119 | */ |
||
120 | function wc_rest_set_uploaded_image_as_attachment( $upload, $id = 0 ) { |
||
121 | $info = wp_check_filetype( $upload['file'] ); |
||
122 | $title = ''; |
||
123 | $content = ''; |
||
124 | |||
125 | if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) { |
||
126 | include_once( ABSPATH . 'wp-admin/includes/image.php' ); |
||
127 | } |
||
128 | |||
129 | View Code Duplication | if ( $image_meta = wp_read_image_metadata( $upload['file'] ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
130 | if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) { |
||
131 | $title = $image_meta['title']; |
||
132 | } |
||
133 | if ( trim( $image_meta['caption'] ) ) { |
||
134 | $content = $image_meta['caption']; |
||
135 | } |
||
136 | } |
||
137 | |||
138 | $attachment = array( |
||
139 | 'post_mime_type' => $info['type'], |
||
140 | 'guid' => $upload['url'], |
||
141 | 'post_parent' => $id, |
||
142 | 'post_title' => $title, |
||
143 | 'post_content' => $content, |
||
144 | ); |
||
145 | |||
146 | $attachment_id = wp_insert_attachment( $attachment, $upload['file'], $id ); |
||
147 | if ( ! is_wp_error( $attachment_id ) ) { |
||
148 | wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $upload['file'] ) ); |
||
149 | } |
||
150 | |||
151 | return $attachment_id; |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * Validate reports request arguments. |
||
156 | * |
||
157 | * @since 2.6.0 |
||
158 | * @param mixed $value |
||
159 | * @param WP_REST_Request $request |
||
160 | * @param string $param |
||
161 | * @return WP_Error|boolean |
||
162 | */ |
||
163 | function wc_rest_validate_reports_request_arg( $value, $request, $param ) { |
||
164 | |||
165 | $attributes = $request->get_attributes(); |
||
166 | View Code Duplication | if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
167 | return true; |
||
168 | } |
||
169 | $args = $attributes['args'][ $param ]; |
||
170 | |||
171 | View Code Duplication | if ( 'string' === $args['type'] && ! is_string( $value ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
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. ![]() |
|||
172 | return new WP_Error( 'woocommerce_rest_invalid_param', sprintf( __( '%1$s is not of type %2$s', 'woocommerce' ), $param, 'string' ) ); |
||
173 | } |
||
174 | |||
175 | if ( 'data' === $args['format'] ) { |
||
176 | $regex = '#^\d{4}-\d{2}-\d{2}$#'; |
||
177 | |||
178 | if ( ! preg_match( $regex, $value, $matches ) ) { |
||
179 | return new WP_Error( 'woocommerce_rest_invalid_date', __( 'The date you provided is invalid.', 'woocommerce' ) ); |
||
180 | } |
||
181 | } |
||
182 | |||
183 | return true; |
||
184 | } |
||
185 | |||
186 | /** |
||
187 | * Encodes a value according to RFC 3986. |
||
188 | * Supports multidimensional arrays. |
||
189 | * |
||
190 | * @since 2.6.0 |
||
191 | * @param string|array $value The value to encode. |
||
192 | * @return string|array Encoded values. |
||
193 | */ |
||
194 | function wc_rest_urlencode_rfc3986( $value ) { |
||
195 | if ( is_array( $value ) ) { |
||
196 | return array_map( 'wc_rest_urlencode_rfc3986', $value ); |
||
197 | } else { |
||
198 | // Percent symbols (%) must be double-encoded. |
||
199 | return str_replace( '%', '%25', rawurlencode( rawurldecode( $value ) ) ); |
||
200 | } |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Check permissions of posts on REST API. |
||
205 | * |
||
206 | * @since 2.6.0 |
||
207 | * @param string $post_type Post type. |
||
208 | * @param string $context Request context. |
||
209 | * @param int $object_id Post ID. |
||
210 | * @return bool |
||
211 | */ |
||
212 | function wc_rest_check_post_permissions( $post_type, $context = 'read', $object_id = 0 ) { |
||
213 | $contexts = array( |
||
214 | 'read' => 'read_private_posts', |
||
215 | 'create' => 'publish_posts', |
||
216 | 'edit' => 'edit_post', |
||
217 | 'delete' => 'delete_post', |
||
218 | 'batch' => 'edit_others_posts', |
||
219 | ); |
||
220 | |||
221 | if ( 'revision' === $post_type ) { |
||
222 | $permission = false; |
||
223 | } else { |
||
224 | $cap = $contexts[ $context ]; |
||
225 | $post_type_object = get_post_type_object( $post_type ); |
||
226 | $permission = current_user_can( $post_type_object->cap->$cap, $object_id ); |
||
227 | } |
||
228 | |||
229 | return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, $post_type ); |
||
230 | } |
||
231 | |||
232 | /** |
||
233 | * Check permissions of users on REST API. |
||
234 | * |
||
235 | * @since 2.6.0 |
||
236 | * @param string $context Request context. |
||
237 | * @param int $object_id Post ID. |
||
238 | * @return bool |
||
239 | */ |
||
240 | function wc_rest_check_user_permissions( $context = 'read', $object_id = 0 ) { |
||
241 | $contexts = array( |
||
242 | 'read' => 'list_users', |
||
243 | 'create' => 'edit_users', |
||
244 | 'edit' => 'edit_users', |
||
245 | 'delete' => 'delete_users', |
||
246 | 'batch' => 'edit_users', |
||
247 | ); |
||
248 | |||
249 | $permission = current_user_can( $contexts[ $context ], $object_id ); |
||
250 | |||
251 | return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, 'user' ); |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Check permissions of product terms on REST API. |
||
256 | * |
||
257 | * @since 2.6.0 |
||
258 | * @param string $taxonomy Taxonomy. |
||
259 | * @param string $context Request context. |
||
260 | * @param int $object_id Post ID. |
||
261 | * @return bool |
||
262 | */ |
||
263 | function wc_rest_check_product_term_permissions( $taxonomy, $context = 'read', $object_id = 0 ) { |
||
264 | $contexts = array( |
||
265 | 'read' => 'manage_terms', |
||
266 | 'create' => 'edit_terms', |
||
267 | 'edit' => 'edit_terms', |
||
268 | 'delete' => 'delete_terms', |
||
269 | 'batch' => 'edit_terms', |
||
270 | ); |
||
271 | |||
272 | $cap = $contexts[ $context ]; |
||
273 | $taxonomy_object = get_taxonomy( $taxonomy ); |
||
274 | $permission = current_user_can( $taxonomy_object->cap->$cap, $object_id ); |
||
275 | |||
276 | return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, $object_id, $taxonomy ); |
||
277 | } |
||
278 | |||
279 | /** |
||
280 | * Check manager permissions on REST API. |
||
281 | * |
||
282 | * @since 2.6.0 |
||
283 | * @param string $object Object. |
||
284 | * @param string $context Request context. |
||
285 | * @return bool |
||
286 | */ |
||
287 | function wc_rest_check_manager_permissions( $object, $context = 'read' ) { |
||
288 | $objects = array( |
||
289 | 'reports' => 'view_woocommerce_reports', |
||
290 | 'settings' => 'manage_woocommerce', |
||
291 | 'attributes' => 'manage_product_terms', |
||
292 | ); |
||
293 | |||
294 | $permission = current_user_can( $objects[ $object ] ); |
||
295 | |||
296 | return apply_filters( 'woocommerce_rest_check_permissions', $permission, $context, 0, $object ); |
||
297 | } |
||
298 |
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.