Been a little stumped after researching and was curious if anyone could provide assistance.
I was curious if there is a way to tap into the WC API and retrieve and order using the endpoint /wp-json/wc/v3/orders but based off of the following meta data:
"id": 3944240,
"key": "_alg_wc_full_custom_order_number",
"value": "D########"
I would like to get an order off that meta data key value of D###### rather than order id or any other parameters their documentation provides, if not possible totally understand just figured id try here!
Thanks!
AFAIK, the WC shop order endpoint doesn't accept meta_key parameter out of the box. But you can hook to the endpoint filter with custom function as below, then you can use the endpoint as such:
/wp-json/wc/v3/orders?custom_order_number=D#####
add_filter( 'woocommerce_rest_shop_order_object_query', 'filter_orders_by_custom_order_number', 100, 2 );
function filter_orders_by_custom_order_number( $args, $request ) {
if( !isset( $request['custom_order_number'] ) ) {
return $args;
}
// add custom query to existing meta_query if exist
if( isset( $args['meta_query'] ) ) {
$args['meta_query']['relation'] = 'AND';
} else {
$args['meta_query'] = array();
}
$args['meta_query'][] = array(
'key' => '_alg_wc_full_custom_order_number',
'value' => $request['custom_order_number']
);
return $args;
}
Related
I need to limit the response's fields of woo commerce Rest API. For example. When I need to show the products of a specific category. I just need product id, image, and slug. So, I wanna get only specific fields. Any way to solve my problem?
You can use the filter hook woocommerce_rest_prepare_product_object to adjust the response.
$wc_rest_api->get('products', array('category' => '1234', 'fields_in_response' => array(
'id',
'images',
'slug'
) ) );
The argument fields_in_response is not there by default.
The following code must be placed on server-side (i.e. in functions.php) to work with it.
add_filter('woocommerce_rest_prepare_product_object', 'at_wc_rest_api_adjust_response_data', 10, 3);
function at_wc_rest_api_adjust_response_data( $response, $object, $request ) {
$params = $request->get_params();
if ( ! $params['fields_in_response'] ) {
return $response;
}
$data = $response->get_data();
$cropped_data = array();
foreach ( $params['fields_in_response'] as $field ) {
$cropped_data[ $field ] = $data[ $field ];
}
$response->set_data( $cropped_data );
return $response;
}
I have a site running an old version of Woo v2.5.5 using legacy v3 for the API. I was able to use the action woocommerce_api_order_response to add data to the orders.
Something like:
add_action( 'woocommerce_api_order_response', 'add_testing_api_function', 10, 1 );
function add_testing_api_function( $order_data ) {
$order_data['foo'] = "testing";
return $order_data;
}
This works fine over the older API link:
https://example.com/wc-api/v3/orders?consumer_key=KEY&consumer_secret=SECRET
However, I need to update to Woo v3.3+ and the REST API is server up as:
https://example.com/wp-json/wc/v2/orders?consumer_key=KEY&consumer_secret=SECRET
My custom data no longer appears, and the hook does not appear to work. Is there another I can use?
WC API is indeed a great tool. Adding your own custom data to WC API shop order's response in WooCommerce 3.x can still be achieved as easily as it used to be with the legacy version of the API.
WooCommerce has these prepare filters for most of their API responses (see). Note that the format of them is woocommerce_rest_prepare_{$post_type}, where $post_type is a post type or taxonomy name like shop_orders or product_cat. In WooCommerce 2.7+ some of these filters also have a _object suffix.
As long as our intent is to add custom data to orders, the right filter to use will be woocommerce_rest_prepare_shop_order_object, where shop_order is our {$post_type} followed the _object suffix (as described above).
The following function conditionally gets user meta and returns the user's social profile's avatar url if available.
/**
* Add custom data to WC API shop order response
* Overriding "$object" here with $order so it's easier to access its properties
*/
function my_wc_rest_prepare_order( $response, $order, $request ) {
if( empty( $response->data ) )
return $response;
$order_id = $order->get_id();
// Get an instance of the WC_Order object
$order = wc_get_order($order_id);
// Get the user ID from WC_Order methods
$user_id = $order->get_customer_id(); // $order->get_user_id(); // or $order->get_customer_id();
// check for WooCommerce Social Login User Avatar
if( class_exists( 'WC_Social_Login' ) ) {
$fb_avatar = get_user_meta( $user_id, '_wc_social_login_facebook_profile_image', true );
$gplus_avatar = get_user_meta( $user_id, '_wc_social_login_google_profile_image', true );
}
$social_data = array();
$avatar_url = array();
$customer_picture = array(
'default' => get_avatar_url( $user_id ),
'facebook' => ( $fb_avatar ) ? esc_url( $fb_avatar ) : '',
'google' => ( $gplus_avatar ) ? esc_url( $gplus_avatar ) : ''
);
$response->data['social_data']['avatar_url'] = $customer_picture;
return $response;
}
add_filter( 'woocommerce_rest_prepare_shop_order_object', 'my_wc_rest_prepare_order', 10, 3 );
Result:
[{
"social_data": {
"avatar_url": {
"default": "https://secure.gravatar.com/avatar/6e27402273b47316097247a2057492f8?s=96&d=mm&r=g",
"facebook": "https://graph.facebook.com/2028542057604385/picture?width=150&height=150",
"google": ""
}
},
}]
Need to be able to sort the results of a REST API custom post query by a meta value.
Having difficulty doing so.
I have made my post type available to the REST API and can order by the Date, Title, etc...
But when I try the Post Meta it doesn't work.
I have added the following code to try and enable the functionality but defaults to ordering by date.
function my_add_meta_vars ($current_vars) {
$current_vars = array_merge ($current_vars, array('meta_key', 'meta_value'));
return $current_vars;
}
add_filter ('query_vars', 'my_add_meta_vars');
add_filter ('rest_query_vars', 'my_add_meta_vars');
My REST API query is
mysite.com/wp-json/wp/v2/hh_equipment?filter[orderby]=meta_value_num&meta_key=equipment_price&order=desc
I have tried following the instructions here to no avail.
Running WordPress 4.8 and tried testing on 4.7 to no avail
I've got it working with the rest_' . $post_type . '_collection_params filter and rest_' . $post_type . '_query filter like so (change $post_type to needed post type slug):
// Add meta your meta field to the allowed values of the REST API orderby parameter
add_filter(
'rest_' . $post_type . '_collection_params',
function( $params ) {
$params['orderby']['enum'][] = 'YOUR_META_KEY';
return $params;
},
10,
1
);
// Manipulate query
add_filter(
'rest_' . $post_type . '_query',
function ( $args, $request ) {
$order_by = $request->get_param( 'orderby' );
if ( isset( $order_by ) && 'YOUR_META_KEY' === $order_by ) {
$args['meta_key'] = $order_by;
$args['orderby'] = 'meta_value'; // user 'meta_value_num' for numerical fields
}
return $args;
},
10,
2
);
The first filter adds your meta field to the possible values of the ordeby parameters, as by default REST API supports only: author, date, id, include, modified, parent, relevance, slug, include_slugs, title (check the ordeby param in the WP REST API handbook)
The second filter allows you to manipulate the query that returns the results when you have your meta key inside the orderby. Here we need to reset orderby to 'meta_value' or 'meta_value_num' (read more about this in WP Query class description) and set the meta key to your custom field key.
Refer below method,
I modified the existing routes to add a new args entry which validates the meta_key values which are permitted. No need to modify the rest query vars this way either.
add_filter('rest_endpoints', function ($routes) {
// I'm modifying multiple types here, you won't need the loop if you're just doing posts
foreach (['some', 'types'] as $type) {
if (!($route =& $routes['/wp/v2/' . $type])) {
continue;
}
// Allow ordering by my meta value
$route[0]['args']['orderby']['enum'][] = 'meta_value_num';
// Allow only the meta keys that I want
$route[0]['args']['meta_key'] = array(
'description' => 'The meta key to query.',
'type' => 'string',
'enum' => ['my_meta_key', 'another key'],
'validate_callback' => 'rest_validate_request_arg',
);
}
return $routes;
});
REF: https://github.com/WP-API/WP-API/issues/2308
I added a new column to Woocommerce orders's screen, that indicates who is the order's creator (in that site, service representatives have the ability to create order for customer's in the backend).The problem is that when I search for that data in the orders screen, I can't find any.
The order's creator is set to the order with add_post_meta()
So I tried something like this:
function include_search( $query ) {
if ( is_admin() && $query->is_search() && $query->query['post_type'] == 'shop_order' ) {
$query->set( 'meta_query', array('key' => 'representative', 'value' => $query->query['s'], 'compare' => '=') );
}
}
add_action( 'pre_get_posts', 'include_search' );
But it doesn't work.
For example, If an order created by "Ben X", then I can see his name appears in the right column in the orders screen, but if I search for "Ben X" in the search box, I don't find that order.
Any help with that?
Thanks!
If anyone need help with that, I found the answer:
function filter_woocommerce_shop_order_search_fields( $array ) {
$array[] = 'representative'; //The order meta key that needs to be include in the search
return $array;
};
add_filter( 'woocommerce_shop_order_search_fields', 'filter_woocommerce_shop_order_search_fields', 10, 1 );
I created another custom statuses to wc statuses, and I want this status to leave the order "editable", so I found this code in the file abstract-wc-order.php:
public function is_editable() {
return apply_filters( 'wc_order_is_editable', in_array( $this->get_status(), array( 'pending', 'on-hold', 'auto-draft', 'failed' ) ), $this );
}
Now if I understand currently, I need to add my custom status to the array above, but I'm not really sure how to do this - to add my status to the above array by hooking the filter wc_order_is_editable, I will really appreciate to any help!
Probably something like this will work:
function so_39193164_is_editable( $editable, $order ) {
if( $order->get_status() == 'your-new-status' ){
$editable = true;
}
return $editable;
}
add_filter( 'wc_order_is_editable', 'so_39193164_is_editable', 10, 2 );
If the order status is your new status then $editable will be true. If not, it will be whatever WooCommerce already decided in the is_editable() method.