WordPress: Combine two loops with different amount of posts - php

I want to show a random selection of 4 new products in WooCommerce.
For that I'm using a first loop to get the 20 newest products.
Like this:
$args= array(
'post_type' => 'product',
'posts_per_page' => 20,
'orderby' => 'date',
);
Now I've a second loop to reduce the products to 4 in a random order:
$args_new = array(
'posts_per_page' => 4,
'orderby' => 'rand',
);
In the end I merge the two loops:
$final_args = array_merge( $args, $args_new );
But that doesn't work. Is there any other way to achieve it?

General knowledge
The post_type argument accept String or Array.
Argument
Description
post_type
(String/Array) – use post types. Retrieves posts by post types, default value is post. If tax_query is set for a query, the default value becomes any.
Source # https://developer.wordpress.org/reference/classes/wp_query/#post-type-parameters
Merging queries
In crude terms we want to combine 2 posts queries, retrieve each posts ID, push them to a new array and open a new query.
Keep in mind that if you want your 4 posts to be random (as you stated in the comments) they might be some duplicates of the last 20 from the first query. Don't forget to offset the second query.
<?php
// First query
$args_1 = get_posts( array(
'post_type' => 'dogs',
'post_status' => 'publish',
'post_count' => 20,
) );
// Second query
$args_2 = get_posts( array(
'post_type' => 'dogs',
'post_status' => 'publish',
'post_count' => 4,
'offset' => 20,
'orderby' => RAND,
) );
// Merge queries
$posts = array_merge( $args_1, $args_2 );
// Push posts IDs to new array
$identifiers = array();
foreach ( $posts as $post ) {
array_push( $identifiers, $post->ID );
};
// Third query
$query = new WP_Query( array(
'post_status' => 'publish',
'post_count' => 24,
'post_in' => array_unique( $identifiers ),
) );
var_dump( $query );

Related

WooCommerce: Get newest products and sort them (partially) randomly

I want to get the last 20 posts (in my case WooCommerce products) and show 10 of them in a random order.
For now I get the new posts like this:
$args = array(
'post_type' => 'product',
'orderby' => 'date',
'order' => 'DESC',
'posts_per_page' => 20,
);
I know that I could get the posts in random order like this:
'orderby' => 'rand',
'posts_per_page' => 10,
But how is it possible to combine these two?
w
Is there a way to store the posts from the first loop and use them in a second loop?
There are several ways to do this, this is one of them
wp_get_recent_posts( array $args = array(), string $output = ARRAY_A ) - Retrieve a number of recent posts.
shuffle ( array &$array ) : bool - This function shuffles (randomizes the order of the elements in) an array. It uses a pseudo random number generator that is not suitable for cryptographic purposes.
array_splice — Remove a portion of the array and replace it with something else
$recent_posts = wp_get_recent_posts( array(
'numberposts' => 20, // Number of recent posts
'post_status' => 'publish', // Show only the published posts
'post_type' => 'product'
));
// array_splice ( array, offset, length )
$sub = array_splice( $recent_posts, 10, 10 );
// Random
shuffle( $sub );
array_splice( $recent_posts, 10, 0, $sub );
// Loop
foreach( $recent_posts as $post ) {
echo $post['ID'] . '<br>';
//echo '<pre>', print_r( $post, 1), '</pre>';
}
wp_reset_query();

Combine two (post) parameters in a single WordPress query

Is there a way to setup a custom WordPress query to get specific post IDs plus children of other specific posts IDs in the same query? I've tried using post_parent__in and post__in parameters but they stop working when combined.
I think this query would help you to achieve your functionality.. Try this query to get all those posts...
$parent = 2; //change as desired or get all parent post ids
$child_args = array(
'post_type' => 'post',
'post_parent' => $parent
);
$keys = array($parent);
$ids = array_merge($keys, array_keys( get_children( $child_args ) ));
$query = new WP_Query(
array(
'post_type' => 'post',
'post_status' => 'publish',
'post__in' => $ids,
'posts_per_page' => -1
)
);

Woocommerce - Guys I'm trying to display 3 random products but skipping the first 3 most recent added products

I need your help. I'm trying to display 3 random products but skipping the first 3 most recently added products. Most recent meaning not by query but by global date the product was created.
Heres the code i use to display random products.
$args = array(
'post_type' => 'product',
'orderby' => 'rand',
'posts_per_page' => 3,
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
}
Adding 'offset' only skips the first 3 random. Is there a way to skip first 3 most recently added products?
First, get three last products and get their IDs using wp_get_recent_posts function and map IDs, then add post__not_in argument to WP_query with these three post IDs
$recent_posts = wp_get_recent_posts([
'post_type' => 'product',
'numberposts' => 3
]);
$last_three_posts = array_map(function($a) { return $a['ID']; }, $recent_posts);
$args = array(
'post_type' => 'product',
'orderby' => 'rand',
'posts_per_page' => 3,
'post__not_in' => $last_three_posts,
);
$loop = new WP_Query( $args );

Get posts belonging to three categories

I want to get posts that match three categories.
For example: if I have three categories, named 1, 2, 3, I want to grab the posts that belong to 1 AND 2 AND 3, and only that posts.
I found a way to make it with two categores:
$args = array(
'category__and' => array(5739,50),
'posts_per_page' => 10,
'orderby' => 'date'
);
But not three.
Thanks in advance.
If you want to show posts from several categories
Then you can display it using following code :
$query = new WP_Query( array( 'cat' => '2,6,17,38' ) );
If you want to show posts from several categories with AND condition
Then you can do it using following code:
$query = new WP_Query( array( 'category__and' => array( 2, 6 ) ) );
If you want to show posts from several categories with OR condition
Then you can do it using following code:
$query = new WP_Query( array( 'category__in' => array( 2, 6 ) ) );
You can use WP_Query for getting posts from multiple categories like:
query_posts( array( 'category__and' => array(34,26,29), 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC' ) );
Here is the helping link:
http://codex.wordpress.org/Class_Reference/WP_Query#Category_Parameters

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);

Categories