Get orders by date and status woocommerce - php

I need get a list of orders in woocommerce passing start date, final date and status.
I tryed use some techniques like described by Mike Jolley, and I mixed with this. But I have not had success. This return all orders. I´m using the woocommerce version 2.2.10.
Thanks for help.
My code:
public function get_orders(){
global $json_api;
$initial_date = $json_api->query->para1;
$final_date = $json_api->query->para2;
$order_id = $json_api->query->para3;
$status_order = $json_api->query->para4;
define('GET_ORDERS_FILTER_DATE_FROM', $initial_date );
define('GET_ORDERS_FILTER_DATE_TO', $final_date );
add_filter('posts_where', array( __CLASS__, 'get_orders_where_dates_between') );
$orders = get_posts( array(
'post_type' => 'shop_order',
'orderby' => 'post_date',
'order' => 'DESC',
'post_status' => array_keys( $status_order )
) );
remove_filter('posts_where', 'order_page_get_orders_where_dates_between');
return $orders;
}
function get_orders_where_dates_between( $where ){
global $wpdb;
if( ! defined('GET_ORDERS_FILTER_DATE_FROM') || ! defined('PARCELWARE_GET_ORDERS_FILTER_DATE_TO') )
return $where;
$where .= $wpdb->prepare(" AND post_date >= '%s' ", GET_ORDERS_FILTER_DATE_FROM);
$where .= $wpdb->prepare(" AND post_date <= '%s' ", GET_ORDERS_FILTER_DATE_TO);
return $where;
}

You can use wc_get_orders
$initial_date = yyyy-mm-dd;
$final_date = yyyy-mm-dd;
$orders = wc_get_orders(array(
'limit'=>-1,
'type'=> 'shop_order',
'status'=> array( 'wc-completed','wc-refunded' ),
'date_created'=> $initial_date .'...'. $final_date
)
);

How about using custom wpdb query like this?
global $wpdb;
$date_from = '2015-11-20';
$date_to = '2015-12-20';
$post_status = implode("','", array('wc-processing', 'wc-completed') );
$result = $wpdb->get_results( "SELECT * FROM $wpdb->posts
WHERE post_type = 'shop_order'
AND post_status IN ('{$post_status}')
AND post_date BETWEEN '{$date_from} 00:00:00' AND '{$date_to} 23:59:59'
");
echo "<pre>";
print_r($result);

If you want to use timestamps (date AND time):
$timestamp_start = '2022-04-07 20:00:00.000'; // example
$timestamp_end = '2022-04-21 20:00:01.000'; // example
'date_created' => strtotime($timestamp_start ) .'...'. strtotime($timestamp_end)

Related

How to get posts order by menu_order in WordPress using $wpdb->get_results()?

I have the following function where I build out my own parent-child navigation.
The issue I'm facing is I have not been able to order the children by menu_order ( so order by the Order attribute that can be set with each page when re-ordered ). Any tips on how to do so would be greatly appreciated.
function wph_get_page_tree( $page_id ){
global $wpdb;
$tree_data = [];
$tree_data[$page_id] = ['title' => get_post($page_id)->post_title, 'ID' => $page_id];
// get 1 level childs
$level_1_childs = [];
$all_childs = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_parent = %d && post_type= 'page' && post_status='publish' ", $page_id ) );
foreach( $all_childs as $single_2_level ){
$level_1_childs[$single_2_level->ID] = ['title' => $single_2_level->post_title, 'ID' => $single_2_level->ID];
//$level_1_childs[$single_2_level->ID] = $single_2_level->post_title;
$all_sub_childs = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_parent = %d && post_type= 'page' && post_status='publish' ", $single_2_level->ID ) );
$level_2_childs = [];
foreach( $all_sub_childs as $single_3_level ){
$level_2_childs[$single_3_level->ID] = ['title' => $single_3_level->post_title, 'ID' => $single_3_level->ID];
}
//var_dump( $level_1_childs );
$level_1_childs[$single_2_level->ID]['childs'] = $level_2_childs;
//var_dump( $level_1_childs );
}
$tree_data[$page_id]['childs'] = $level_1_childs;
//var_dump( $tree_data );
return $tree_data;
}
You need to pass ORDER BY {$wpdb->posts}.menu_order ASC to your query. check the below code.
function wph_get_page_tree( $page_id ){
global $wpdb;
$tree_data = [];
$tree_data[$page_id] = ['title' => get_post($page_id)->post_title, 'ID' => $page_id];
// get 1 level childs
$level_1_childs = [];
$all_childs = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_parent = %d && post_type= 'page' && post_status='publish' ORDER BY {$wpdb->posts}.menu_order ASC ", $page_id ) );
foreach( $all_childs as $single_2_level ){
$level_1_childs[$single_2_level->ID] = ['title' => $single_2_level->post_title, 'ID' => $single_2_level->ID];
//$level_1_childs[$single_2_level->ID] = $single_2_level->post_title;
$all_sub_childs = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_parent = %d && post_type= 'page' && post_status='publish' ORDER BY {$wpdb->posts}.menu_order ASC ", $single_2_level->ID ) );
$level_2_childs = [];
foreach( $all_sub_childs as $single_3_level ){
$level_2_childs[$single_3_level->ID] = ['title' => $single_3_level->post_title, 'ID' => $single_3_level->ID];
}
//var_dump( $level_1_childs );
$level_1_childs[$single_2_level->ID]['childs'] = $level_2_childs;
//var_dump( $level_1_childs );
}
$tree_data[$page_id]['childs'] = $level_1_childs;
//var_dump( $tree_data );
return $tree_data;
}

I have a query that works fine with the first letter of the name tag but wont work with numbers?

I have a wordpress query to search for the initial letter of the name tag as follows.
$args = array(
'post_type' => 'movies',
'orderby' => 'title',
'order' => ASC,
'posts_per_page' => -1
'ignore_sticky_posts' => TRUE,
'substring_where' => 'A',
);
And in the functions.php
function restrict_by_first_letter( $where, $qry ) {
global $wpdb;
$sub = $qry->get('substring_where');
if (!empty($sub)) {
$where .= $wpdb->prepare(
" AND SUBSTRING( {$wpdb->posts}.post_title, 1, 1 ) = %s ", $sub
);
}
return $where;
}
add_filter( 'posts_where' , 'restrict_by_first_letter', 1 , 2 );
?>
Which works great but doesn't work with numbers ?
Any input would be much apprecianed.
Put single quotes around '%s' in your query statement:
function restrict_by_first_letter( $where, $qry ) {
global $wpdb;
$sub = $qry->get('substring_where');
if (!empty($sub)) {
$where .= $wpdb->prepare(
" AND SUBSTRING( {$wpdb->posts}.post_title, 1, 1 ) = CONVERT('%s',char) ", $sub
);
}
return $where;
}
add_filter( 'posts_where' , 'restrict_by_first_letter', 1 , 2 );
?>

Get All WP Posts older than 15 minutes

I would like to filter the WP_Query to retrive all woocommerce order (post_type = shop_order) with particular status that are older than 15 minutes.
I.e. All posts that have been last modified on or before (now - 15 minutes ) // Hope I'm clear.
Below What I've tried
function filter_where($where = '') {
//posts in the last 15 minutes
$where .= " AND post_modified > '" . date('Y-m-d', strtotime('INTERVAL 15 MINUTE')) . "'";
return $where;
}
add_filter('posts_where', 'filter_where');
$args = array(
'post_type' => 'shop_order',
'post_status' => 'publish',
'posts_per_page' => 10,
'tax_query' => array(
array(
'taxonomy' => 'shop_order_status',
'field' => 'slug',
'terms' => array('completed')
)
)
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
print_r("<pre>");
print_r($order);
print_r("</pre>");
endwhile;
However that returns all record, Seems like have to modify the $where query, how can i achieve that ?
Do you need to filter the posts_where? Can't you just use date query parameters? In your case, specifically before.
$args = array(
'date_query' => array(
array(
'before' => '15 minutes ago'
'inclusive' => true,
),
),
'posts_per_page' => -1,
);
$query = new WP_Query( $args );
I can't test this right now, so can't verify if it would work. If you are modifying an archive then you should definitely adjust the query via pre_get_posts in lieu of creating new query.
try this change date('Y-m-d', strtotime('INTERVAL 15 MINUTE')) to date('Y-m-d H:i:s', strtotime('-15 minutes'))
function filter_where($where = ''){
//posts in the last 15 minutes
$where .= " AND post_modified > '" . date('Y-m-d H:i:s', strtotime('-15 minutes')) . "'";
return $where;
}
add_filter('posts_where', 'filter_where');

In Wordpress, can I use WP_Query with timestamp?

I have code like this,
$date_arg = array(
'after' => array(
'year' => $num_days_ago['year'],
'month' => $num_days_ago['mon'],
'day' => $num_days_ago['mday'],
),
'inclusive' => false,
);
$query = new WP_Query( array ( 'date_query' => $date_arg, 'post_type' => $post_type ...
This is working fine but I have to specify a exact date. Is it possible to use "timestamp" to make the query.
For example, I want to query posts that is within 24 hours. I can get the timestamp by
$ts = time() - DAY_IN_SECONDS
It is possible to get the posts that is created after $ts?
You could try constructing a date using the date() and strtotime() functions.
$date_query = array(
'after' => date('Y-m-d H:i:s', strtotime('-24 hours'))
);
I'd also recommend taking a look at this handy website - http://www.viper007bond.com/tag/wp_date_query/
IMHO better like so :
function filter_where($where = '') {
$where .= " AND post_date > '" . date('Y-m-d H:i:s', strtotime('-24 hours')) . "'";
return $where;
}
add_filter('posts_where', 'filter_where');
and more general :
// Create a new filtering function that will add our where clause to the query
function filter_where( $where = '' ) {
// posts in the last x days
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";// here 30
return $where;
}
add_filter( 'posts_where', 'filter_where' ); // add the filter before setting object or before loop
$query = new WP_Query( $query_string );
remove_filter( 'posts_where', 'filter_where' ); // .. and do not forget to remove it
Or you could try something like this
SELECT post_title, IF (post_date_gmt < (DATE_SUB(CURDATE(), INTERVAL 24 HOUR)), 'false', 'true') AS A FROM wp_posts
WHERE post_type = "post" AND post_status = "publish"
http://www.w3schools.com/sql/func_date_sub.asp

$wpdb query not running

I'm working on a wpdb query and it's just not running. And for some reason the error reporting for wpdb isn't giving me any errors.
So, can anyone spot an obvious mistake in this query?
I'm attempting to get the meta_value of all _sell_media_attached_file keys in the post_meta table.
I'm first running a wp_query , getting the post ID's and then running each post ID through the wpdb query.
Here's what I'm working with:
// run the loop
$loop = new WP_Query( array(
'post_type' => 'sell_media_item',
'collection' => $club,
'include_children' => false,
'year' => $year,
'monthnum' => $month,
'day' => $day,
'fields' => 'ids',
) );
if ( $post_ids = $loop->get_posts() ) {
$post_ids = implode( ',', $post_ids );
//breaks here
$atts_ids = $wpdb->get_col( "SELECT meta_value FROM $wpdb->postmeta WHERE post_id = $post_ids AND meta_key = '_sell_media_attached_file' " );
echo('<b>query:</b> <pre>'); var_dump($atts_ids);
But as I say, nothing get's output in the var_dump and if I add $wpdb->print_error(); I get no errors.
In your piece of code i didn't see the initialization of wpdb class to access the wpdb class in your wordpress you have to define it as the global to access the functions of the class and also if $post_ids contains the multiple ids with comma separated you have to use the IN() clause instead of = operator
global $wpdb;
// run the loop
$loop = new WP_Query( array(
'post_type' => 'sell_media_item',
'collection' => $club,
'include_children' => false,
'year' => $year,
'monthnum' => $month,
'day' => $day,
'fields' => 'ids',
'nopaging'=>true
) );
if ( $post_ids = $loop->get_posts() ) {
$post_ids = implode( ',', $post_ids );
//breaks here
$atts_ids = $wpdb->get_col( "SELECT meta_value FROM $wpdb->postmeta WHERE post_id IN($post_ids) AND meta_key = '_sell_media_attached_file' " );
echo('<b>query:</b> <pre>'); var_dump($atts_ids);
why not try something like that?
if( $loop->have_posts() ){
$ids = $loop->get_posts();
foreach( $ids as $id ){
$atts_ids[] = get_post_meta($id, '_sell_media_attached_file', true|false ); //true if single value false if multiple values return as array
}
}else{
//Do something else
}
Hope it helps!

Categories