1111use WCPOS \WooCommercePOS \Logger ;
1212use WP_REST_Request ;
1313use WP_REST_Response ;
14+ use function in_array ;
15+ use function is_array ;
16+ use function is_callable ;
1417use const WCPOS \WooCommercePOS \PLUGIN_NAME ;
1518use WC_Order_Query ;
1619use WP_Query ;
@@ -33,6 +36,8 @@ public function __construct( WP_REST_Request $request ) {
3336 $ this ->incoming_shop_order ();
3437 }
3538
39+ add_filter ( 'rest_request_before_callbacks ' , array ( $ this , 'rest_request_before_callbacks ' ), 10 , 3 );
40+ add_filter ( 'woocommerce_rest_shop_order_object_query ' , array ( $ this , 'order_query ' ), 10 , 2 );
3641 add_filter ('woocommerce_rest_pre_insert_shop_order_object ' , array (
3742 $ this ,
3843 'pre_insert_shop_order_object ' ,
@@ -50,6 +55,88 @@ public function __construct( WP_REST_Request $request ) {
5055 add_filter ( 'option_woocommerce_tax_based_on ' , array ( $ this , 'tax_based_on ' ), 10 , 2 );
5156 }
5257
58+ /**
59+ * Filters the response before executing any REST API callbacks.
60+ *
61+ * We can use this filter to bypass data validation checks
62+ *
63+ * @param WP_REST_Response|WP_HTTP_Response|WP_Error|mixed $response Result to send to the client.
64+ * Usually a WP_REST_Response or WP_Error.
65+ * @param array $handler Route handler used for the request.
66+ * @param WP_REST_Request $request Request used to generate the response.
67+ */
68+ public function rest_request_before_callbacks ( $ response , $ handler , $ request ) {
69+ if ( is_wp_error ( $ response ) ) {
70+ // Check if the error code 'rest_invalid_param' exists
71+ if ( $ response ->get_error_message ( 'rest_invalid_param ' ) ) {
72+ // Get the error data for 'rest_invalid_param'
73+ $ error_data = $ response ->get_error_data ( 'rest_invalid_param ' );
74+
75+ // Check if the invalid parameter was 'line_items'
76+ if ( array_key_exists ( 'line_items ' , $ error_data ['params ' ] ) ) {
77+ // Get the 'line_items' details
78+ $ line_items_details = $ error_data ['details ' ]['line_items ' ];
79+
80+ // Check if 'line_items[X][quantity]' has 'rest_invalid_type'
81+ // Use a regular expression to match 'line_items[X][quantity]', where X is a number
82+ if ( $ line_items_details ['code ' ] === 'rest_invalid_type ' &&
83+ preg_match ( '/^line_items\[\d+\]\[quantity\]$/ ' , $ line_items_details ['data ' ]['param ' ] ) ) {
84+ if ( woocommerce_pos_get_settings ( 'general ' , 'decimal_qty ' ) ) {
85+ unset( $ error_data ['params ' ]['line_items ' ], $ error_data ['details ' ]['line_items ' ] );
86+ }
87+ }
88+ }
89+
90+ // Check if the invalid parameter was 'billing'
91+ if ( array_key_exists ( 'billing ' , $ error_data ['params ' ] ) ) {
92+ // Get the 'billing' details
93+ $ billing_details = $ error_data ['details ' ]['billing ' ];
94+
95+ // Check if 'billing' has 'rest_invalid_email'
96+ if ( $ billing_details ['code ' ] === 'rest_invalid_email ' ) {
97+ unset( $ error_data ['params ' ]['billing ' ], $ error_data ['details ' ]['billing ' ] );
98+ }
99+ }
100+
101+ // Check if the invalid parameter was 'orderby'
102+ if ( array_key_exists ( 'orderby ' , $ error_data ['params ' ] ) ) {
103+ // Get the 'orderby' details
104+ $ orderby_details = $ error_data ['details ' ]['orderby ' ];
105+
106+ // Get the 'orderby' request
107+ $ orderby_request = $ request ->get_param ( 'orderby ' );
108+
109+ // Extended 'orderby' values
110+ $ orderby_extended = array (
111+ 'status ' ,
112+ 'customer_id ' ,
113+ 'payment_method ' ,
114+ 'total ' ,
115+ );
116+
117+ // Check if 'orderby' has 'rest_not_in_enum', but is in the extended 'orderby' values
118+ if ( $ orderby_details ['code ' ] === 'rest_not_in_enum ' && in_array ( $ orderby_request , $ orderby_extended , true ) ) {
119+ unset( $ error_data ['params ' ]['orderby ' ], $ error_data ['details ' ]['orderby ' ] );
120+ }
121+ }
122+
123+ // Check if $error_data['params'] is empty
124+ if ( empty ( $ error_data ['params ' ] ) ) {
125+ return null ;
126+ } else {
127+ // Remove old error data and add new error data
128+ $ error_message = 'Invalid parameter(s): ' . implode ( ', ' , array_keys ( $ error_data ['params ' ] ) ) . '. ' ;
129+
130+ $ response ->remove ( 'rest_invalid_param ' );
131+ $ response ->add ( 'rest_invalid_param ' , $ error_message , $ error_data );
132+ }
133+ }
134+ }
135+
136+ return $ response ;
137+ }
138+
139+
53140
54141 public function incoming_shop_order (): void {
55142 $ raw_data = $ this ->request ->get_json_params ();
@@ -97,6 +184,19 @@ public function test_email() {
97184 return true ;
98185 }
99186
187+ /**
188+ * Filter the query arguments for a request.
189+ *
190+ * @param array $args Key value array of query var to query value.
191+ * @param WP_REST_Request $request The request used.
192+ *
193+ * @return array $args Key value array of query var to query value.
194+ */
195+ public function order_query ( $ args , WP_REST_Request $ request ) {
196+
197+ return $ args ;
198+ }
199+
100200 /**
101201 * @param $order
102202 * @param $request
@@ -191,18 +291,18 @@ public function rest_set_order_item( $item, $posted ): void {
191291 $ variation = wc_get_product ( (int ) $ posted ['variation_id ' ] );
192292 $ valid_keys = array ();
193293
194- if ( \ is_callable ( array ( $ variation , 'get_variation_attributes ' ) ) ) {
294+ if ( is_callable ( array ( $ variation , 'get_variation_attributes ' ) ) ) {
195295 foreach ( $ variation ->get_variation_attributes () as $ attribute_name => $ attribute ) {
196296 $ valid_keys [] = str_replace ( 'attribute_ ' , '' , $ attribute_name );
197297 }
198298
199- if ( isset ( $ posted ['meta_data ' ] ) && \ is_array ( $ posted ['meta_data ' ] ) ) {
299+ if ( isset ( $ posted ['meta_data ' ] ) && is_array ( $ posted ['meta_data ' ] ) ) {
200300 foreach ( $ posted ['meta_data ' ] as $ meta ) {
201301 // fix initial item creation
202302 if ( isset ( $ meta ['attr_id ' ] ) ) {
203303 if ( 0 == $ meta ['attr_id ' ] ) {
204304 // not a taxonomy
205- if ( \ in_array ( strtolower ( $ meta ['display_key ' ] ), $ valid_keys , true ) ) {
305+ if ( in_array ( strtolower ( $ meta ['display_key ' ] ), $ valid_keys , true ) ) {
206306 $ item ->add_meta_data ( strtolower ( $ meta ['display_key ' ] ), $ meta ['display_value ' ], true );
207307 }
208308 } else {
@@ -219,7 +319,7 @@ public function rest_set_order_item( $item, $posted ): void {
219319 }
220320 }
221321 // fix subsequent overwrites
222- if ( wc_attribute_taxonomy_id_by_name ( $ meta ['key ' ] ) || \ in_array ( $ meta ['key ' ], $ valid_keys , true ) ) {
322+ if ( wc_attribute_taxonomy_id_by_name ( $ meta ['key ' ] ) || in_array ( $ meta ['key ' ], $ valid_keys , true ) ) {
223323 $ item ->add_meta_data ( $ meta ['key ' ], $ meta ['value ' ], true );
224324 }
225325 }
@@ -295,28 +395,28 @@ public function orderby_additions( array $clauses, WP_Query $wp_query ): array {
295395 // add option to order by status
296396 if ( 'status ' === $ wp_query ->query_vars ['orderby ' ] ) {
297397 $ clauses ['join ' ] .= " LEFT JOIN {$ wpdb ->prefix }posts AS order_posts ON {$ wpdb ->prefix }posts.ID = order_posts.ID " ;
298- $ clauses ['orderby ' ] = " order_posts.post_status " . $ order ;
398+ $ clauses ['orderby ' ] = ' order_posts.post_status ' . $ order ;
299399 }
300400
301401 // add option to order by customer_id
302402 if ( 'customer_id ' === $ wp_query ->query_vars ['orderby ' ] ) {
303403 $ clauses ['join ' ] .= " LEFT JOIN {$ wpdb ->prefix }postmeta AS customer_meta ON {$ wpdb ->prefix }posts.ID = customer_meta.post_id " ;
304404 $ clauses ['where ' ] .= " AND customer_meta.meta_key = '_customer_user' " ;
305- $ clauses ['orderby ' ] = " customer_meta.meta_value " . $ order ;
405+ $ clauses ['orderby ' ] = ' customer_meta.meta_value ' . $ order ;
306406 }
307407
308408 // add option to order by payment_method
309409 if ( 'payment_method ' === $ wp_query ->query_vars ['orderby ' ] ) {
310410 $ clauses ['join ' ] .= " LEFT JOIN {$ wpdb ->prefix }postmeta AS payment_method_meta ON {$ wpdb ->prefix }posts.ID = payment_method_meta.post_id " ;
311411 $ clauses ['where ' ] .= " AND payment_method_meta.meta_key = '_payment_method' " ;
312- $ clauses ['orderby ' ] = " payment_method_meta.meta_value " . $ order ;
412+ $ clauses ['orderby ' ] = ' payment_method_meta.meta_value ' . $ order ;
313413 }
314414
315415 // add option to order by total
316416 if ( 'total ' === $ wp_query ->query_vars ['orderby ' ] ) {
317417 $ clauses ['join ' ] .= " LEFT JOIN {$ wpdb ->prefix }postmeta AS total_meta ON {$ wpdb ->prefix }posts.ID = total_meta.post_id " ;
318418 $ clauses ['where ' ] .= " AND total_meta.meta_key = '_order_total' " ;
319- $ clauses ['orderby ' ] = " total_meta.meta_value+0 " . $ order ;
419+ $ clauses ['orderby ' ] = ' total_meta.meta_value+0 ' . $ order ;
320420 }
321421 }
322422
0 commit comments