Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
An example plugin to show the use of the PHP SPL and subsidiary loops with a FilterIterator.
<?php
// Reduced to the minimum
class ThumbnailFilter extends FilterIterator
{
private $wp_query;
public function __construct( Iterator $iterator, WP_Query $wp_query )
{
NULL === $this->wp_query AND $this->wp_query = $wp_query;
parent::__construct( $iterator );
}
public function accept()
{
$this->wp_query->the_post();
$this->wp_query->current_post === $this->wp_query->query_vars['posts_per_page'] // -1
AND $this->wp_query->rewind_posts();
return $this->wp_query->have_posts() AND $this->deny();
}
public function deny()
{
return ! has_post_thumbnail( $this->current()->ID );
}
}
<?php
/**
* Plugin Name: (#130009) Merge Two Queries
* Description: "Merges" two queries by using a <code>RecursiveFilterIterator</code> to divide one main query into two queries
* Plugin URl: http://wordpress.stackexchange.com/questions/130009/how-to-merge-two-queries-together
*/
class ThumbnailFilter extends FilterIterator implements Countable
{
private $wp_query;
private $allowed;
private $counter = 0;
public function __construct( Iterator $iterator, WP_Query $wp_query )
{
NULL === $this->wp_query AND $this->wp_query = $wp_query;
// Save some processing time by saving it once
NULL === $this->allowed
AND $this->allowed = $this->wp_query->have_posts();
parent::__construct( $iterator );
}
public function accept()
{
if (
! $this->allowed
OR ! $this->current() instanceof WP_Post
)
return FALSE;
// Switch index, Setup post data, etc.
$this->wp_query->the_post();
// Last WP_Post reached: Setup WP_Query for next loop
$this->wp_query->current_post === $this->wp_query->query_vars['posts_per_page'] // -1
AND $this->wp_query->rewind_posts();
// Doesn't meet criteria? Abort.
if ( $this->deny() )
return FALSE;
$this->counter++;
return TRUE;
}
public function deny()
{
return ! has_post_thumbnail( $this->current()->ID );
}
public function count()
{
return $this->counter;
}
}
class NoThumbnailFilter extends ThumbnailFilter
{
public function deny()
{
return has_post_thumbnail( $this->current()->ID );
}
}
add_action( 'loop_start', 'wpse130009Query' );
function wpse130009Query()
{
// Only need to remove this callback for the current test
// Else we'd infinitely nest this callback as WP_Query::the_post()
// calls the 'loop_start' filter.
remove_action( current_filter(), __FUNCTION__ );
global $wp_query;
echo number_format_i18n( $wp_query->found_posts );
$arrayObj = new ArrayObject( $wp_query->get_posts() );
$primaryQuery = new ThumbnailFilter( $arrayObj->getIterator(), $wp_query );
$secondaryQuery = new NoThumbnailFilter( $arrayObj->getIterator(), $wp_query );
foreach ( $primaryQuery as $post )
{
var_dump( get_the_ID() );
}
foreach ( $secondaryQuery as $post )
{
var_dump( get_the_ID() );
}
}
@franz-josef-kaiser
Copy link
Author

franz-josef-kaiser commented Jan 18, 2021

I am not sure what you are up to. The WP.SE answer explains whats's happening here. If you got a different question, please ask a follow up question on WP.SE directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment