Created
January 10, 2014 14:42
-
-
Save gmazzap/8355403 to your computer and use it in GitHub Desktop.
Simlpe plugin coded to refactor the code posted on a WPSE anwser
This file contains hidden or 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: 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