I want to get the processing order count in WooCommerce. I'm using the following code in the Code Snippet plugin but that is working.
if( !function_exists( 'wc_processing_order_count' ) ) {
require_once '../plugins/woocommerce/includes/wc-order-functions.php';
}
// NOTICE! Understand what this does before running.
$result = wc_processing_order_count();
It's returning nothing.
This custom function use a very light SQL query to get the orders count from a specific status:
function get_orders_count_from_status( $status ){
global $wpdb;
// We add 'wc-' prefix when is missing from order staus
$status = 'wc-' . str_replace('wc-', '', $status);
return $wpdb->get_var("
SELECT count(ID) FROM {$wpdb->prefix}posts WHERE post_status LIKE '$status' AND `post_type` LIKE 'shop_order'
");
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Usage example for "processing" orders count:
// Display "processing" orders count
echo get_orders_count_from_status( "processing" );
Both the answers above are way too complicated for something so simple.
Simplest way is this :)
$processing_orders_count = count(wc_get_orders( array(
'status' => 'processing',
'return' => 'ids',
'limit' => -1,
)));
This method could help you. The order is stored as post_type shop_order. So by creating query to get all posts of type shop_order and by passing arguments to get all processing order, you will be able to get those orders
$args = array(
'post_type' => 'shop_order',
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'shop_order_status',
'field' => 'slug',
'terms' => array('processing')
)
)
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ){
$loop->the_post();
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
}
Take a look at: https://github.com/woocommerce/woocommerce/wiki/wc_get_orders-and-WC_Order_Query
That reference really helped me in a similar situation.
Using the WC functions ensures your code is more future proof compared to using a hardcoded query or WP_Query as mentioned in other answers.
Related
I want to display the total number of purchases made on my site to my site users; Previously, I wrote the code that displayed the total number of products published on my site, and now I want the code to display the total number of successful purchases from my site to the user.
The code I wrote to display the number of products on my site is as follows:
function product_count_shortcode() {
$count_posts = wp_count_posts( 'product' );
return $count_posts->publish;
}
add_shortcode( 'product_counthalsho', 'product_count_shortcode' );
You will basically have to show the number of orders that have the status completed. Just create a function that will query the order post_type and with the status completed.
You can simply use get_posts and use the php function count the check how many results you have, or use WP_Query that already has a property in the return object that tells you how many orders you have with that status.
Later Edit:
function mrc_total_completed_orders() {
$args = array(
'post_type' => 'order',
'posts_per_page' => -1,
'post_status' => 'completed',
);
$orders = get_posts( $args );
return count( $orders ); }
Or you can use the WC_Order_Query
function mrc_mrc_total_completed_Orders() {
$query = new WC_Order_Query( array(
'limit' => 99999,
'status' => array( 'completed' ),
'return' => 'ids',
) );
$orders = $query->get_orders();
return count( $orders ); }
Also some documentation here
Note that I haven't tested these solutions, but its enough to get you started :)
Usage:
echo mrc_mrc_total_completed_Orders();
I'm stuck on something that I'm sure must be pretty simple but is getting me nuts. I'm forced at work to use WordPress, which I have zero experience with, and I'm struggling so far to understand how it operates regarding hooks and filters.
What I want is pretty simple:I'm using the latest posts block to display posts written by users. Except that the page I'm working on would be the front end for the website's moderator who would have to see the posts with the 'pending' status, not the 'publish' one. I couldn't find any option to change that in the editor, so I'm trying to set a hook to change the query from 'post_status' => 'publish' to 'post_status' => 'pending', but it's not working, I get a 'Oops! That page can’t be found.'
Here's what I wrote in my functions.php:
function name_of_the_function( $query ) {
if( get_query_var('pagename') == 'name_of_the_page' && current_user_can('publish_posts') && $query->is_main_query() ) {
$query->set( 'post_status', 'pending' );
return $query;
}
}
add_filter( 'pre_get_posts', 'name_of_the_function' );
If I leave this function exactly like that but write 'publish' instead of 'pending' the page displays correctly the last published posts, but with 'pending' I get the message I mentioned before. And I tried with add_action instead of add_filter and got hte same results.
I'd like to add that I do have pending posts awaiting, and if I write the following in my page template, they are found:
$args = array (
'cat' => 5,
'post_status' => 'pending'
);
$query = new WP_Query( $args );
while ( $query->have_posts() ) {
$query->the_post();
echo get_the_title();
}
Just to check, directly in the wp-includes/latest-posts.php file, I changed :
$args = array(
'posts_per_page' => $attributes['postsToShow'],
'post_status' => 'publish',
'order' => $attributes['order'],
'orderby' => $attributes['orderBy'],
'suppress_filters' => false,
);
to :
$args = array(
'posts_per_page' => $attributes['postsToShow'],
'post_status' => 'pending',
'order' => $attributes['order'],
'orderby' => $attributes['orderBy'],
'suppress_filters' => false,
);
It works and displays the pending posts but of course I can't use that as the file would be erased at every WordPress update.
Sorry for the long post but I'm lost now and don't know what else to do, I've looked all other the intrnet but can't find an answer to this, I would really appreciate any help regarding that matter, thanks in advance.
By using the pre_get_posts with $query->is_main_query(), you apply this to the query that WordPress uses to find the page (the main query). Your code needs to be changed to:
function name_of_the_function( $query ) {
if ( is_admin() || $query->is_main_query() ) {
return $query;
}
if( get_query_var('pagename') == 'name_of_the_page' && current_user_can('publish_posts') ) {
$query->set( 'post_status', 'pending' );
}
return $query;
}
add_filter( 'pre_get_posts', 'name_of_the_function' );
So basically, don't run this on any query in the admin or any query that is the main query, but only run it on a specific page for people with specific capabilities.
So I'm new to coding in Wordpress an woocommerce too!
I want to list all completed orders in the front end of a Wordpress site, order number and item ordered.
I have created a template file and I can get it run basic PHP such as echo and foreach, but I can't get my head around how to list completed orders!
however, the below code doesn't return any orders.
I found the commented out SQL statement which is more what I'm after i.e. return all orders that have a date of x in a text meta field. but I have no idea of how to include it in the template file!
<?php
/**
* Template Name: PPR List
*/
wp_head();
Echo "testing";
//"SELECT post_id FROM wp_postmeta WHERE meta_key = 'arrival_date' AND meta_value <= $today"
$all_orders = get_posts( array(
'numberposts' => $order_count,
'post_type' => wc_get_order_types( 'complete' ),
'post_status' => array_keys( wc_get_order_statuses() )
) );
echo '<pre>'; print_r($array); echo '</pre>';
wp_footer();
Using WC_Order_Query is a lighter and simpler way
wc_get_orders and WC_Order_Query provide a standard way of retrieving orders that is safe to use and will not break due to database changes in future WooCommerce versions.
Source: wc_get_orders and WC_Order_Query
So you get
$args = array(
'status' => 'completed', // Accepts a string: one of 'pending', 'processing', 'on-hold', 'completed', 'refunded, 'failed', 'cancelled', or a custom order status.
'meta_key' => 'arrival_date', // Postmeta key field
'meta_value' => $today, // Postmeta value field
'meta_compare' => '<=', // Possible values are ‘=’, ‘!=’, ‘>’, ‘>=’, ‘<‘, ‘<=’, ‘LIKE’, ‘NOT LIKE’, ‘IN’, ‘NOT IN’, ‘BETWEEN’, ‘NOT BETWEEN’, ‘EXISTS’ (only in WP >= 3.5), and ‘NOT EXISTS’ (also only in WP >= 3.5). Values ‘REGEXP’, ‘NOT REGEXP’ and ‘RLIKE’ were added in WordPress 3.7. Default value is ‘=’.
);
$orders = wc_get_orders( $args );
foreach ( $orders as $order ) {
$order_id = $order->get_id();
echo '<p>' . $order_id . '</p>';
}
Might come in handy: How to get WooCommerce order details
I am trying to generate a list of available coupons and to display them using a shortcode. I was hoping to generate the list using SQL and not "-1" since that's heavier on the db from what I understand.
The error I get is this: Notice: Array to string conversion
add_shortcode('ac', 'coupon_list' );
function coupon_list() {
// array for coupons, was hoping for a sql query instead but don't know how
$args = array(
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'asc',
'post_type' => 'shop_coupon',
'post_status' => 'publish',
);
$coupons = get_posts( $args );
$coupon_names = array();
foreach ( $coupons as $coupon ) {
$coupon_name = $coupon->post_title;
array_push( $coupon_names, $coupon_name );
}
// display all available coupons on product page
echo $coupon_names;
}
There are 2 mistakes in your code: You are trying to display an array with echo and when using a shortcode function the data to display requires to be returned (not echoed).
The following function (shortcode), will display a coma separated string of all available coupon codes using a light SQL Query:
add_shortcode('ac', 'available_coupon_codes' );
function available_coupon_codes() {
global $wpdb;
// Get an array of all existing coupon codes
$coupon_codes = $wpdb->get_col("SELECT post_name FROM $wpdb->posts WHERE post_type = 'shop_coupon' AND post_status = 'publish' ORDER BY post_name ASC");
// Display available coupon codes
return implode(', ', $coupon_codes) ; // always use return in a shortcode
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
USAGE:
1) In the WordPress text editor of a post, a custom post or a page:
[ac]
2) On a php file or template:
echo available_coupon_codes();
or
echo do_shortcode('[ac]');
With a WP_Query (like in your code):
add_shortcode('ac', 'coupon_list' );
function coupon_list() {
$coupon_posts = get_posts( array(
'posts_per_page' => -1,
'orderby' => 'name',
'order' => 'asc',
'post_type' => 'shop_coupon',
'post_status' => 'publish',
) );
$coupon_codes = []; // Initializing
foreach( $coupon_posts as $coupon_post) {
$coupon_codes[] = $coupon_post->post_name;
}
// Display available coupon codes
return implode(', ', $coupon_codes) ; // always use return in a shortcode
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Same usage than the first function
I can't get order objects with status of wc-pending / Pending Payment. It simply returns ALL the order objects:
$my_course_query = new WP_Query( array(
'post_type' => 'shop_order',
'post_status' => 'wc-pending',
'posts_per_page' => -1
) );
Your code Is just working perfectly as expected, in frontend, I have test it and it output only orders with **pending status. So I can't tell what is your issue as your question is not detailed.
I have found this note on WordPress WP_Query reference that could be useful:
Note: Ticket #18408 For querying posts in the admin, consider using get_posts() as wp_reset_postdata() might not behave as expected.
In general, I don't use WP_Query() for customer orders but wc_get_orders() (or get_posts() too) this way:
$customer_orders = wc_get_orders( array(
'limit' => -1,
'status' => 'pending'
) );
// Iterating through each Order with pending status
foreach ( $customer_orders as $order ) {
// Going through each current customer order items
foreach($order->get_items() as $item_id => $item_values){
$product_id = $item_values['product_id']; // product ID
// Order Item meta data
$item_meta_data = wc_get_order_item_meta( $item_id );
// Some output
echo '<p>Line total for '.wc_get_order_item_meta( $item_id, '_line_total', true ).'</p><br>';
}
}
This works also just to get the orders objects.
Related documentation: wc_get_orders and WC_Order_Query
I fixed this weird issue by simply using custom query.
Somehow adding 'post_status' => 'wc-pending' doesn't actually change the query, but if I use 'post_status' => 'pending', the query changes.
So what I did was using that custom query and modify pending to wc-pending.
I do have the same issue (returning ALL Orders) while debugging.
Wrapping the debug-code into an action helped outputting the expected data:
add_action( 'init', 'debug_init' );
function debug_init() {
$custom_query_args = array(
"fields" => "ids",
"post_type" => "shop_order",
"post_status" => array('wc-processing'),
"posts_per_page" => "-1",
"offset" => "0",
"date_query" => [
"before" => "2020-09-10 23:59",
"after" => "1970-01-01 00:00",
"inclusive" => "1"
],
"order" => "DESC"
);
$debugQuery = new WP_Query( $custom_query_args );
$order_ids = $debugQuery->posts;
print_r($order_ids);
die();
}