First, sorry for my ignorance in this field and I will try to express myself clear.
I am trying to use wc_get_orders
to get orders from Woocommerce with the following args
$args = array(
'limit' => $rows_per_page,
'paged' => $page,
'paginate' => true,
'customer' => $filter
);
$results = wc_get_orders($args);
$orders = $results->orders;
code taken from https://github.com/woocommerce/woocommerce/wiki/wc_get_orders-and-WC_Order_Query#customer and modified by me.
$filter
is a partial string of customer name or email. With this setup, I can only filter and receive result when $filter
is full: [email protected]
. I am trying to partially match %@woo%
just like in MySQL with no luck.
Currently, I solve this with a raw query as follow (I understand that it is not a best practice and can break when woo commerce update their database):
global $wpdb;
$rows_per_page = intval((isset($_POST['rowsPerPage'])) ? sanitize_text_field($_POST['rowsPerPage']) : '5');
$page = intval((isset($_POST['page'])) ? sanitize_text_field($_POST['page']) : '1');
$filter = ((isset($_POST['filter'])) ? sanitize_text_field($_POST['filter']) : '') === 'undefined' ? '' : $_POST["filter"];
$skip = ($page - 1) * $rows_per_page;
$sqlCount = "
SELECT
SQL_CALC_FOUND_ROWS {$wpdb->prefix}posts.ID
FROM
{$wpdb->prefix}posts
WHERE
1 = 1
AND wp_posts.post_type = 'shop_order'
AND (
(
{$wpdb->prefix}posts.post_status = 'wc-pending'
OR {$wpdb->prefix}posts.post_status = 'wc-processing'
OR {$wpdb->prefix}posts.post_status = 'wc-on-hold'
OR {$wpdb->prefix}posts.post_status = 'wc-completed'
OR {$wpdb->prefix}posts.post_status = 'wc-cancelled'
OR {$wpdb->prefix}posts.post_status = 'wc-refunded'
OR {$wpdb->prefix}posts.post_status = 'wc-failed'
)
)
AND {$wpdb->prefix}posts.ID IN (
SELECT post_id AS order_id
FROM {$wpdb->prefix}postmeta
WHERE meta_key
IN ('_billing_first_name', '_billing_email', '_billing_phone' )
AND meta_value LIKE '%" . $filter . "%'
)
ORDER BY
{$wpdb->prefix}posts.post_date DESC
";
$sql = "
SELECT
SQL_CALC_FOUND_ROWS {$wpdb->prefix}posts.ID
FROM
{$wpdb->prefix}posts
WHERE
1 = 1
AND wp_posts.post_type = 'shop_order'
AND (
(
{$wpdb->prefix}posts.post_status = 'wc-pending'
OR {$wpdb->prefix}posts.post_status = 'wc-processing'
OR {$wpdb->prefix}posts.post_status = 'wc-on-hold'
OR {$wpdb->prefix}posts.post_status = 'wc-completed'
OR {$wpdb->prefix}posts.post_status = 'wc-cancelled'
OR {$wpdb->prefix}posts.post_status = 'wc-refunded'
OR {$wpdb->prefix}posts.post_status = 'wc-failed'
)
)
AND {$wpdb->prefix}posts.ID IN (
SELECT post_id AS order_id
FROM {$wpdb->prefix}postmeta
WHERE meta_key
IN ('_billing_first_name', '_billing_email', '_billing_phone' )
AND meta_value LIKE '%" . $filter . "%'
)
ORDER BY
{$wpdb->prefix}posts.post_date DESC
LIMIT
" . $skip . ", " . $rows_per_page . "
";
$orders = $wpdb->get_results($sql);
$rowcount = count($wpdb->get_results($sqlCount));
I am not entirely happy with my raw sql setup because it may not be the best way to do such thing and I need to run 2 sql queries, one to get the paginated result, one to count the number of results returned. Is there a better way to do this?
Thank you very much.
2
Answers
I found out how to do this. First, this is my
$args
:To this point
wc_get_orders
won't work.$results = wc_get_orders($args);
We need to tell Wordpress/WooCommerce to take the
meta_query
into consideration:This wonderful code is from this answer: https://wordpress.stackexchange.com/a/337865
Using
LIKE
insidewc_get_orders()
with custom values can be done like the above code snippet. You can find more details here