Get all Woocommerce product IDs in an array - php

How do I get IDs of all products in one array?
The output should be a simple array containing some numbers, nothing more.
I have been advised against using query_posts(), so I would prefer a solution not using this function.

There is multiple ways to get all product ids in an array:
1) Using Woocommerce WC_Product_Query:
$ids = wc_get_products( array( 'return' => 'ids', 'limit' => -1 ) );
2) Using Wordpress WP_Query (including product variations IDs),
$ids = get_posts( array(
'posts_per_page' => -1,
'post_type' => array('product','product_variation'),
'fields' => 'ids',
) );
3) Using a WPDB (a SQL query) (including product variation IDS):
global $wpdb;
$ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->prefix}posts WHERE post_type IN ('product','product_variation')");
In the 2 last ways you can remove 'product_variation' post type, if you don't want it.

Related

Wordpress arguments to filter WP query

I'm currently grabbing some posts using SQL. I am wanting to use some arguments in the posts I have grabbed. Is this possible? I'm trying to limit the amount of posts returned per page to paginate it. I usually use the args array. Can the args array work with this?
$get_posts = $wpdb->get_results("SELECT id FROM wp_posts WHERE post_type = 'job_listing'");
Of course it can, you just need to get the IDs from the database in a flat array, but you don't really need to query the database directly.
$args = array(
'post_type' => 'job_listing',
'post_status' => 'publish',
'posts_per_page' => 10,
'paged' => get_query_var('paged', 1),
'post__in' => $get_posts,
);
Complete reference

Get processing status orders count in WooCommerce?

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.

How to limit the number of fetched items by a WP_Query

The 'posts_per_page' is not limiting the number of items WP_Query will fetch.
Which is OK, however I need to find a way how to break the WP_Query with some limit or break like attribute after 3 items are fetched. I have many items and to fetch 3 items it get all the 1000+ items in my database, which is slowing down the page in the end.
Any idea how to limit the query to get only 3 instead of all items from the db?
$args = array(
'post_type' => array( 'books' ),
'meta_query' => array(
array(
'key' => 'book_state',
'value' => 'sold'
)
),
'posts_per_page' => 3,
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
$booksNumber = $the_query->found_posts; // returns 1282 instead of 3
...
found_posts returns the total number of posts matching the query parameters.
post_count returns the total number of posts being displayed. I believe what you want to do is:
$booksNumber = $the_query->post_count;
If that doesn't work, I would try using get_posts instead of WP_Query:
$postslist = get_posts($args);
$booksNumber = count($postslist);
It looks like you're only using one meta query, so try using get_posts.
Normally, I'd recommend WP_Query, but I can see how it can be confusing. If you run the following code you will see something more like what you're expecting:
$args = array(
'post_type' => 'books',
'meta_key' => 'book_state',
'meta_value' => 'sold',
'posts_per_page' => 3,
);
$posts = get_posts($args);
echo count($posts);
var_dump($posts);

How to order by two different things at once in a query in WordPress

I am having a little problem. I am trying to get the latest 12 post by a custom meta field. Out of those 12 posts, I want to order them by post date. So first I pull 12 posts out using a custom meta field and ordering them to find the latest through the meta field. Once I have them, then I want to re-order them with latest post.
Here is my current code, I don't know how I can put two order-bys in one query...
$recentEpisodes12 = new WP_Query(array(
'posts_per_page' => 12,
'post_type' => 'post',
'meta_key' => 'air_date',
'order' => 'DESC',
'orderby' => 'meta_value_num',
'meta_query' => array(
array(
'key' => 'air_date',
),
array(
'key' => 'already_aired',
'value' => 'yes',
'compare' => '='
)
),
));
In WordPress 4.2 and up, ordering by one or more custom fields was made much easier. See this link for examples: https://make.wordpress.org/core/2015/03/30/query-improvements-in-wp-4-2-orderby-and-meta_query/
You can even order one column ASC and another DESC by passing an array to orderby now:
'orderby' => array(
'city_clause' => 'ASC',
'state_clause' => 'DESC',
),
According to the Codex, you simply need to separate them by a space:
Multiple 'orderby' values
Display pages ordered by 'title' and 'menu_order'. (title is
dominant):
$query = new WP_Query( array( 'post_type' => 'page', 'orderby' => 'title menu_order', 'order' => 'ASC' ) );
In your case, that would look like:
'orderby' => 'meta_value_num date'
EDIT: Okay, it seems like you're trying to do something a bit more complex here. This is how I interpret it, correct my if I'm wrong:
Order by air_date (in descending order, newest first).
Keep only the 12 newest items according to air_date.
Order the resulting 12 items by date.
What orderby does is basically:
Order by air_date.
If any items have identical air_date values, order those by date.
Keep only the top 12 items.
The difference is that you only want to distinguish by air_date, whereas the normal usage of orderby uses both criteria to determine which items end up in the result.
I don't know an easy way to solve this, though. However, since you only want to change the display order of the resulting items, you could just sort those yourself. You can use get_posts instead of WP_Query and sort the results array using PHP's usort
$posts = get_posts(...);
usort($posts, '__sort_by_date_desc');
function __sort_by_date_desc($a, $b) {
// Make timestamps from MySQL datetime values
$a_date = mysql2date('U', $a->post_date);
$b_date = mysql2date('U', $b->post_date);
// Descending order, swap these for ascending
return $b_date - $a_date;
}
So if you want to order them by post date, why do you need a meta field for that? Once you get the 12 latest posts by meta value, is the air_date somehow different from the post date?
Worth noting: posts_per_page doesn't limit the total number of returns. It just tells WordPress when to split into a new page.
Something like this should work based on what you described in your original post.
// Post Criteria
$post_criteria = array(
'posts_per_page' => 12, // Don't paginate until after 12 posts
'orderby' => 'post_date', // Order by post date
'order' => 'DESC', // Order them reverse chronologically (ie. get the newest first)
'meta_key' => 'air_date', // Only get posts with this meta key
'meta_value' => 'meta_value_num', // And this meta value (only needed if you have multiple possible values for the meta key and just want one)
'post_type' => 'post', // Only get posts
'post_status' => 'publish'); // Only get posts that are published (ie. no drafts, etc.)
// Get posts matching criteria
$posts = get_posts( $post_criteria );
// Discard posts after the 12th one
$posts = array_slice($posts, 0, 12);
// If you wanted to reverse them to display
// chronologically, uncomment this variable.
# $posts = array_reverse($posts);
// For each post
foreach ($posts as $post) {
// Basic variables
// See a full list here: http://codex.wordpress.org/Function_Reference/get_post#Return
$id = $post->ID;
$title = $post->post_title;
$url = get_permalink($id);
$content = $post->post_content;
// Do stuff with the posts here.
}

Sorting posts in a customized order

I have a "custom Page" set up and I am trying to figure out how I can make it arrange the posts it pulls in a specific order...I am thinking of using the custom fields. But not sure how to add a listing of a numeric value.
For Lease and For Sale
List item Size List item (ie 1 br, 2br, 3br) (least expensive
first)
List item Price (Cheapest to most expensive)
You can order order posts by custom fields. The query will be something like this:
$query = new WP_Query( array ( 'post_type' => 'custom_page', 'order' => 'DESC', 'orderby' => 'meta_value', 'meta_key' => 'price' ) );
In your case, you will have to convert price and size to pure numeric values for the sorting to work. For Lease and Sale, I would suggest you should not rely on sorting but use it to query, something like this:
$query = new WP_Query( array( 'post_type' => 'custom_page', 'meta_key' => 'deed', 'meta_value' => 'lease' ) );

Categories