Skip to content

Instantly share code, notes, and snippets.

@gmazzap
Created January 10, 2014 14:42
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gmazzap/8355403 to your computer and use it in GitHub Desktop.
Save gmazzap/8355403 to your computer and use it in GitHub Desktop.
Simlpe plugin coded to refactor the code posted on a WPSE anwser
<?php
/**
* Plugin Name: Cpt In Main Query By Meta
* Plugin URI: http://wordpress.stackexchange.com/questions/129236/
* Description: Allow mixing a post type with another on main query, only if the second match some meta query args
* Author: Giuseppe Mazzapica
* Author URI: http://wordpress.stackexchange.com/users/35541/g-m
*/
/*************************************************************************************************
*
* To make the plugin works, it needs to set up (passing to class constructor)
* a CPT name and some meta query args (see codex.wordpress.org/Class_Reference/WP_Meta_Query)
* both can be setted via filters: 'cpt_by_meta_in_home' and 'cpt_by_meta_in_home_args'
* E.g.:
*
*
* add_action('init', function() {
*
* add_filter( 'cpt_in_main_query_by_meta', function() {
* // SET HERE THE CPT NAME
* return 'my-cpt';
* });
*
* add_filter( 'cpt_in_main_query_by_meta_args', function() {
* // SET HERE THE META QUERY ARGS
* return array(
* 'key' => 'my_custom_key',
* 'value' => 'value_your_are_looking_for',
* 'compare' => '='
* );
* });
*
* });
*
*
*************************************************************************************************/
class CptInMainQueryByMeta {
/**
* @var array $filtered helper variable that allow run filter only once
* @access private
*/
private $filtered = array();
/**
* @var array $filters the sql fiter generated by WP_Meta_Query
* @access private
*/
private $filters = array();
/**
* @var array $args the arguments for WP_Meta_Query
* @access private
*/
private $args = array();
/**
* @var string $cpt the name of CPT to be added on home page
* @access private
*/
private $cpt = '';
/**
* Constructor, check the arguments and start the add-to-query process
*
* @param string $cpt the name of CPT to be added on home page
* @param array $args the arguments for WP_Meta_Query
* @access public
*/
function __construct( $cpt = '', $args = array() ) {
if ( ! empty($cpt) ) {
$types = get_post_types( array( 'public' => TRUE ) );
if ( in_array( $cpt, $types ) && ! empty( $args ) && is_array( $args ) ) {
$this->cpt = $cpt;
$this->args = $args;
add_action('pre_get_posts', array( $this, 'filters' ) );
}
}
}
/**
* Add filter hooks on main query for home archive
* run on pre_get_posts
*
* @param WP_Query $query the query being runned
* @return NULL
* @access public
*/
function filters( WP_Query $query = null ) {
if ( current_filter() !== 'pre_get_posts' ) return;
if ( $query->is_main_query() && ! is_admin() && is_home() ) {
add_filter( 'posts_where', array( $this, 'filter' ) );
add_filter( 'posts_join', array( $this, 'filter' ) );
}
}
/**
* Add filter hooks on main query for home archive
* run on pre_get_posts
*
* @param WP_Query $query the query being runned
* @return string the filtered SQL where or join clause
* @access public
*/
function filter( $sql = '' ) {
$filter = current_filter();
if ( ! in_array( $filter, array('posts_where', 'posts_join'), TRUE ) ) return;
// run once per filter
if ( isset( $this->filtered[$filter] ) ) return $sql;
$this->filtered[$filter] = 1;
$this->get_sql();
if ( current_filter() === 'posts_where' && isset( $this->filters['where'] ) ) {
return $this->where();
}
if ( current_filter() === 'posts_join' && isset( $this->filters['join'] ) ) {
return $sql .= $this->filters['join'];
}
}
/**
* Return the where clause merging post type condition with clause generated by WP_Meta_Query
*
* @return string the SQL where clause
* @access private
*/
private function where() {
global $wpdb;
$where = "AND ($wpdb->posts.post_status = 'publish') ";
$where .= "AND ( $wpdb->posts.post_type = 'post' OR ( ";
$where .= $wpdb->prepare( "$wpdb->posts.post_type = %s", $this->cpt);
$where .= $this->filters['where'] . ' ) )';
$where .= " GROUP BY $wpdb->posts.ID ";
return $where;
}
/**
* Generate where an joing clause using WP_Meta_Query and arguments passed to constructor
*
* @return string the SQL where clause
* @access private
*/
private function get_sql() {
if ( empty( $this->filters ) ) {
$meta_query = new WP_Meta_Query( array( $this->args ) );
$this->filters = $meta_query->get_sql('post', $GLOBALS['wpdb']->posts, 'ID');
}
}
}
// Three, two, one, go!
add_action('wp_loaded', function() {
$cpt = apply_filters( 'cpt_in_main_query_by_meta', '' );
$args = apply_filters( 'cpt_in_main_query_by_meta_args', array() );
if ( ! empty($cpt) && is_string($cpt) && ! empty($args) && is_array($args) ) {
new CptInMainQueryByMeta($cpt, $args);
}
}, 30 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment