Create a gist now

Instantly share code, notes, and snippets.

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() );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment