Last active
December 4, 2018 16:44
-
-
Save birgire/439e36a6b08f1159f653 to your computer and use it in GitHub Desktop.
WordPress: The Sponsor Posts Injector plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The Sponsor Posts Injector - Usage Example | |
* | |
* @version 0.0.3 | |
* @uses content-sponsor.php | |
* @file functions.php | |
* @see http://wordpress.stackexchange.com/q/158133/26350 | |
*/ | |
/** | |
* Inject a sponsor post after the first post on the home page, | |
* and then again for every third post within the main query. | |
*/ | |
add_action( 'wp', 'my_sponsor_injections' ); | |
function my_sponsor_injections() | |
{ | |
if( ! class_exists( 'SponsorPostsInjector' ) ) return; | |
// We want the sponsor post injections only on the home page: | |
if( ! is_home() ) return; | |
// Setup the injection: | |
$injector = new SponsorPostsInjector( | |
array( | |
'items_before_each_inject' => 3, | |
'items_per_inject' => 1, | |
'template_part' => 'content-sponsor', | |
) | |
); | |
// Setup the injection query: | |
$injector->query( | |
array( | |
'post_type' => 'sponsor', | |
'tax_query' => array( | |
array( | |
'taxonomy' => 'country', | |
'terms' => 'sweden', | |
'field' => 'slug', | |
) | |
) | |
) | |
); | |
// Inject: | |
$injector->inject(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: Sponsor Posts Injector | |
* Description: This plugin helps you to automatically inject sponsor posts into the loop. You must use custom code to start the injection. See the example. | |
* Plugin URI: http://wordpress.stackexchange.com/a/141612/26350 | |
* Author: birgire | |
* Author URI: https://github.com/birgire | |
* License: GPL2+ | |
* Version: 0.0.3 | |
*/ | |
/** | |
* class SponsorPostsInjector | |
* | |
* Inject custom posts into the main loop, through hooks, | |
* with only a single WP_Query() call | |
* | |
* @link http://wordpress.stackexchange.com/a/141612/26350 | |
* | |
* Definitions: | |
* Posts per page: PPP | |
* Custom post type: Y | |
* Main query post type: X | |
* How many Y posts to inject: y | |
* How many X posts to display before injecting the Y posts: x | |
* | |
* Formula: | |
* PPP(Y) = y * floor( ( PPP(X) -1 ) / x ) | |
* where PPP(X), x and y are positive | |
*/ | |
class SponsorPostsInjector | |
{ | |
protected $results = null; | |
protected $query = null; | |
protected $nr = 0; | |
protected $inject_mode = false; | |
protected $args = array(); | |
protected $query_args = array(); | |
public function __construct( $args = array() ) | |
{ | |
$defaults = array( | |
'items_before_each_inject' => 1, | |
'items_per_inject' => 1, | |
'template_part' => 'content-page', | |
); | |
$this->args = wp_parse_args( $args, $defaults ); | |
} | |
public function query( $query_args = array() ) | |
{ | |
$defaults = array( | |
'paged' => ( $pgd = get_query_var( 'paged' ) ) ? $pgd : 1, | |
'suppress_filters' => true, | |
); | |
$this->query_args = wp_parse_args( $query_args, $defaults ); | |
} | |
public function inject() | |
{ | |
add_action( 'loop_start', array( $this, 'loop_start' ) ); | |
add_action( 'loop_end', array( $this, 'loop_end' ) ); | |
} | |
public function items_on_this_page( WP_Query $query ) | |
{ | |
$count = $this->args['items_per_inject'] * floor( ( $query->get( 'posts_per_page' ) -1 ) / $this->args['items_before_each_inject'] ); | |
return ( $count > 0 ) ? $count : 1; | |
} | |
public function loop_start( WP_Query $query ) | |
{ | |
$this->query = $query; | |
if( $query->is_main_query() ) | |
{ | |
$this->query_args['posts_per_page'] = $this->items_on_this_page( $query ); | |
$this->results = new WP_Query( $this->query_args ); | |
add_action( 'the_post', array( $this, 'the_post' ) ); | |
} | |
} | |
public function loop_end( WP_Query $query ) | |
{ | |
if( $query->is_main_query() ) | |
remove_action( 'the_post', array( $this, 'the_post' ) ); | |
} | |
public function the_post() | |
{ | |
if( ! $this->inject_mode | |
&& 0 < $this->nr | |
&& 0 === $this->nr % $this->args['items_before_each_inject'] ) | |
{ | |
$this->inject_mode = true; | |
$this->results->rewind_posts(); | |
$this->results->current_post = ( absint( $this->nr / $this->args['items_before_each_inject'] ) -1 ) * $this->args['items_per_inject'] - 1; | |
$j = 1; | |
if ( $this->results->have_posts() ) : | |
while ( $this->results->have_posts() ) : | |
$this->results->the_post(); | |
get_template_part( $this->args['template_part'] ); | |
if( $this->args['items_per_inject'] < ++$j ) | |
break; | |
endwhile; | |
wp_reset_postdata(); | |
endif; | |
$this->inject_mode = false; | |
} | |
if( ! $this->inject_mode ) | |
$this->nr++; | |
} | |
} // end class |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment