Created
October 20, 2014 08:00
-
-
Save kwando/c68f555aeaa8e9c7b284 to your computer and use it in GitHub Desktop.
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
/** | |
* Retrieve the posts based on query variables. | |
* | |
* There are a few filters and actions that can be used to modify the post | |
* database query. | |
* | |
* @since 1.5.0 | |
* @access public | |
* @uses do_action_ref_array() Calls 'pre_get_posts' hook before retrieving posts. | |
* | |
* @return array List of posts. | |
*/ | |
function get_posts() { | |
global $wpdb, $user_ID, $_wp_using_ext_object_cache; | |
$this->parse_query(); | |
do_action_ref_array('pre_get_posts', array(&$this)); | |
// Shorthand. | |
$q = &$this->query_vars; | |
// Fill again in case pre_get_posts unset some vars. | |
$q = $this->fill_query_vars($q); | |
// Parse meta query | |
$this->meta_query = new WP_Meta_Query(); | |
$this->meta_query->parse_query_vars( $q ); | |
// Set a flag if a pre_get_posts hook changed the query vars. | |
$hash = md5( serialize( $this->query_vars ) ); | |
if ( $hash != $this->query_vars_hash ) { | |
$this->query_vars_changed = true; | |
$this->query_vars_hash = $hash; | |
} | |
unset($hash); | |
// First let's clear some variables | |
$distinct = ''; | |
$whichauthor = ''; | |
$whichmimetype = ''; | |
$where = ''; | |
$limits = ''; | |
$join = ''; | |
$search = ''; | |
$groupby = ''; | |
$fields = ''; | |
$post_status_join = false; | |
$page = 1; | |
if ( isset( $q['caller_get_posts'] ) ) { | |
_deprecated_argument( 'WP_Query', '3.1', __( '"caller_get_posts" is deprecated. Use "ignore_sticky_posts" instead.' ) ); | |
if ( !isset( $q['ignore_sticky_posts'] ) ) | |
$q['ignore_sticky_posts'] = $q['caller_get_posts']; | |
} | |
if ( !isset( $q['ignore_sticky_posts'] ) ) | |
$q['ignore_sticky_posts'] = false; | |
if ( !isset($q['suppress_filters']) ) | |
$q['suppress_filters'] = false; | |
if ( !isset($q['cache_results']) ) { | |
if ( $_wp_using_ext_object_cache ) | |
$q['cache_results'] = false; | |
else | |
$q['cache_results'] = true; | |
} | |
if ( !isset($q['update_post_term_cache']) ) | |
$q['update_post_term_cache'] = true; | |
if ( !isset($q['update_post_meta_cache']) ) | |
$q['update_post_meta_cache'] = true; | |
if ( !isset($q['post_type']) ) { | |
if ( $this->is_search ) | |
$q['post_type'] = 'any'; | |
else | |
$q['post_type'] = ''; | |
} | |
$post_type = $q['post_type']; | |
if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 ) | |
$q['posts_per_page'] = get_option('posts_per_page'); | |
if ( isset($q['showposts']) && $q['showposts'] ) { | |
$q['showposts'] = (int) $q['showposts']; | |
$q['posts_per_page'] = $q['showposts']; | |
} | |
if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) ) | |
$q['posts_per_page'] = $q['posts_per_archive_page']; | |
if ( !isset($q['nopaging']) ) { | |
if ( $q['posts_per_page'] == -1 ) { | |
$q['nopaging'] = true; | |
} else { | |
$q['nopaging'] = false; | |
} | |
} | |
if ( $this->is_feed ) { | |
$q['posts_per_page'] = get_option('posts_per_rss'); | |
$q['nopaging'] = false; | |
} | |
$q['posts_per_page'] = (int) $q['posts_per_page']; | |
if ( $q['posts_per_page'] < -1 ) | |
$q['posts_per_page'] = abs($q['posts_per_page']); | |
else if ( $q['posts_per_page'] == 0 ) | |
$q['posts_per_page'] = 1; | |
if ( !isset($q['comments_per_page']) || $q['comments_per_page'] == 0 ) | |
$q['comments_per_page'] = get_option('comments_per_page'); | |
if ( $this->is_home && (empty($this->query) || $q['preview'] == 'true') && ( 'page' == get_option('show_on_front') ) && get_option('page_on_front') ) { | |
$this->is_page = true; | |
$this->is_home = false; | |
$q['page_id'] = get_option('page_on_front'); | |
} | |
if ( isset($q['page']) ) { | |
$q['page'] = trim($q['page'], '/'); | |
$q['page'] = absint($q['page']); | |
} | |
// If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present. | |
if ( isset($q['no_found_rows']) ) | |
$q['no_found_rows'] = (bool) $q['no_found_rows']; | |
else | |
$q['no_found_rows'] = false; | |
switch ( $q['fields'] ) { | |
case 'ids': | |
$fields = "$wpdb->posts.ID"; | |
break; | |
case 'id=>parent': | |
$fields = "$wpdb->posts.ID, $wpdb->posts.post_parent"; | |
break; | |
default: | |
$fields = "$wpdb->posts.*"; | |
} | |
if ( '' !== $q['menu_order'] ) | |
$where .= " AND $wpdb->posts.menu_order = " . $q['menu_order']; | |
// If a month is specified in the querystring, load that month | |
if ( $q['m'] ) { | |
$q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']); | |
$where .= " AND YEAR($wpdb->posts.post_date)=" . substr($q['m'], 0, 4); | |
if ( strlen($q['m']) > 5 ) | |
$where .= " AND MONTH($wpdb->posts.post_date)=" . substr($q['m'], 4, 2); | |
if ( strlen($q['m']) > 7 ) | |
$where .= " AND DAYOFMONTH($wpdb->posts.post_date)=" . substr($q['m'], 6, 2); | |
if ( strlen($q['m']) > 9 ) | |
$where .= " AND HOUR($wpdb->posts.post_date)=" . substr($q['m'], 8, 2); | |
if ( strlen($q['m']) > 11 ) | |
$where .= " AND MINUTE($wpdb->posts.post_date)=" . substr($q['m'], 10, 2); | |
if ( strlen($q['m']) > 13 ) | |
$where .= " AND SECOND($wpdb->posts.post_date)=" . substr($q['m'], 12, 2); | |
} | |
if ( '' !== $q['hour'] ) | |
$where .= " AND HOUR($wpdb->posts.post_date)='" . $q['hour'] . "'"; | |
if ( '' !== $q['minute'] ) | |
$where .= " AND MINUTE($wpdb->posts.post_date)='" . $q['minute'] . "'"; | |
if ( '' !== $q['second'] ) | |
$where .= " AND SECOND($wpdb->posts.post_date)='" . $q['second'] . "'"; | |
if ( $q['year'] ) | |
$where .= " AND YEAR($wpdb->posts.post_date)='" . $q['year'] . "'"; | |
if ( $q['monthnum'] ) | |
$where .= " AND MONTH($wpdb->posts.post_date)='" . $q['monthnum'] . "'"; | |
if ( $q['day'] ) | |
$where .= " AND DAYOFMONTH($wpdb->posts.post_date)='" . $q['day'] . "'"; | |
// If we've got a post_type AND it's not "any" post_type. | |
if ( !empty($q['post_type']) && 'any' != $q['post_type'] ) { | |
foreach ( (array)$q['post_type'] as $_post_type ) { | |
$ptype_obj = get_post_type_object($_post_type); | |
if ( !$ptype_obj || !$ptype_obj->query_var || empty($q[ $ptype_obj->query_var ]) ) | |
continue; | |
if ( ! $ptype_obj->hierarchical || strpos($q[ $ptype_obj->query_var ], '/') === false ) { | |
// Non-hierarchical post_types & parent-level-hierarchical post_types can directly use 'name' | |
$q['name'] = $q[ $ptype_obj->query_var ]; | |
} else { | |
// Hierarchical post_types will operate through the | |
$q['pagename'] = $q[ $ptype_obj->query_var ]; | |
$q['name'] = ''; | |
} | |
// Only one request for a slug is possible, this is why name & pagename are overwritten above. | |
break; | |
} //end foreach | |
unset($ptype_obj); | |
} | |
if ( '' != $q['name'] ) { | |
$q['name'] = sanitize_title_for_query( $q['name'] ); | |
$where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'"; | |
} elseif ( '' != $q['pagename'] ) { | |
if ( isset($this->queried_object_id) ) { | |
$reqpage = $this->queried_object_id; | |
} else { | |
if ( 'page' != $q['post_type'] ) { | |
foreach ( (array)$q['post_type'] as $_post_type ) { | |
$ptype_obj = get_post_type_object($_post_type); | |
if ( !$ptype_obj || !$ptype_obj->hierarchical ) | |
continue; | |
$reqpage = get_page_by_path($q['pagename'], OBJECT, $_post_type); | |
if ( $reqpage ) | |
break; | |
} | |
unset($ptype_obj); | |
} else { | |
$reqpage = get_page_by_path($q['pagename']); | |
} | |
if ( !empty($reqpage) ) | |
$reqpage = $reqpage->ID; | |
else | |
$reqpage = 0; | |
} | |
$page_for_posts = get_option('page_for_posts'); | |
if ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) { | |
$q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) ); | |
$q['name'] = $q['pagename']; | |
$where .= " AND ($wpdb->posts.ID = '$reqpage')"; | |
$reqpage_obj = get_post( $reqpage ); | |
if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) { | |
$this->is_attachment = true; | |
$post_type = $q['post_type'] = 'attachment'; | |
$this->is_page = true; | |
$q['attachment_id'] = $reqpage; | |
} | |
} | |
} elseif ( '' != $q['attachment'] ) { | |
$q['attachment'] = sanitize_title_for_query( wp_basename( $q['attachment'] ) ); | |
$q['name'] = $q['attachment']; | |
$where .= " AND $wpdb->posts.post_name = '" . $q['attachment'] . "'"; | |
} | |
if ( $q['w'] ) | |
$where .= ' AND ' . _wp_mysql_week( "`$wpdb->posts`.`post_date`" ) . " = '" . $q['w'] . "'"; | |
if ( intval($q['comments_popup']) ) | |
$q['p'] = absint($q['comments_popup']); | |
// If an attachment is requested by number, let it supersede any post number. | |
if ( $q['attachment_id'] ) | |
$q['p'] = absint($q['attachment_id']); | |
// If a post number is specified, load that post | |
if ( $q['p'] ) { | |
$where .= " AND {$wpdb->posts}.ID = " . $q['p']; | |
} elseif ( $q['post__in'] ) { | |
$post__in = implode(',', array_map( 'absint', $q['post__in'] )); | |
$where .= " AND {$wpdb->posts}.ID IN ($post__in)"; | |
} elseif ( $q['post__not_in'] ) { | |
$post__not_in = implode(',', array_map( 'absint', $q['post__not_in'] )); | |
$where .= " AND {$wpdb->posts}.ID NOT IN ($post__not_in)"; | |
} | |
if ( is_numeric( $q['post_parent'] ) ) { | |
$where .= $wpdb->prepare( " AND $wpdb->posts.post_parent = %d ", $q['post_parent'] ); | |
} elseif ( $q['post_parent__in'] ) { | |
$post_parent__in = implode( ',', array_map( 'absint', $q['post_parent__in'] ) ); | |
$where .= " AND {$wpdb->posts}.post_parent IN ($post_parent__in)"; | |
} elseif ( $q['post_parent__not_in'] ) { | |
$post_parent__not_in = implode( ',', array_map( 'absint', $q['post_parent__not_in'] ) ); | |
$where .= " AND {$wpdb->posts}.post_parent NOT IN ($post_parent__not_in)"; | |
} | |
if ( $q['page_id'] ) { | |
if ( ('page' != get_option('show_on_front') ) || ( $q['page_id'] != get_option('page_for_posts') ) ) { | |
$q['p'] = $q['page_id']; | |
$where = " AND {$wpdb->posts}.ID = " . $q['page_id']; | |
} | |
} | |
// If a search pattern is specified, load the posts that match | |
if ( !empty($q['s']) ) { | |
// added slashes screw with quote grouping when done early, so done later | |
$q['s'] = stripslashes($q['s']); | |
if ( empty( $_GET['s'] ) && $this->is_main_query() ) | |
$q['s'] = urldecode($q['s']); | |
if ( !empty($q['sentence']) ) { | |
$q['search_terms'] = array($q['s']); | |
} else { | |
preg_match_all('/".*?("|$)|((?<=[\r\n\t ",+])|^)[^\r\n\t ",+]+/', $q['s'], $matches); | |
$q['search_terms'] = array_map('_search_terms_tidy', $matches[0]); | |
} | |
$n = !empty($q['exact']) ? '' : '%'; | |
$searchand = ''; | |
foreach( (array) $q['search_terms'] as $term ) { | |
$term = esc_sql( like_escape( $term ) ); | |
$search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))"; | |
$searchand = ' AND '; | |
} | |
if ( !empty($search) ) { | |
$search = " AND ({$search}) "; | |
if ( !is_user_logged_in() ) | |
$search .= " AND ($wpdb->posts.post_password = '') "; | |
} | |
} | |
// Allow plugins to contextually add/remove/modify the search section of the database query | |
$search = apply_filters_ref_array('posts_search', array( $search, &$this ) ); | |
// Taxonomies | |
if ( !$this->is_singular ) { | |
$this->parse_tax_query( $q ); | |
$clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' ); | |
$join .= $clauses['join']; | |
$where .= $clauses['where']; | |
} | |
if ( $this->is_tax ) { | |
if ( empty($post_type) ) { | |
// Do a fully inclusive search for currently registered post types of queried taxonomies | |
$post_type = array(); | |
$taxonomies = wp_list_pluck( $this->tax_query->queries, 'taxonomy' ); | |
foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) { | |
$object_taxonomies = $pt === 'attachment' ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt ); | |
if ( array_intersect( $taxonomies, $object_taxonomies ) ) | |
$post_type[] = $pt; | |
} | |
if ( ! $post_type ) | |
$post_type = 'any'; | |
elseif ( count( $post_type ) == 1 ) | |
$post_type = $post_type[0]; | |
$post_status_join = true; | |
} elseif ( in_array('attachment', (array) $post_type) ) { | |
$post_status_join = true; | |
} | |
} | |
// Back-compat | |
if ( !empty($this->tax_query->queries) ) { | |
$tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' ); | |
if ( !empty( $tax_query_in_and ) ) { | |
if ( !isset( $q['taxonomy'] ) ) { | |
foreach ( $tax_query_in_and as $a_tax_query ) { | |
if ( !in_array( $a_tax_query['taxonomy'], array( 'category', 'post_tag' ) ) ) { | |
$q['taxonomy'] = $a_tax_query['taxonomy']; | |
if ( 'slug' == $a_tax_query['field'] ) | |
$q['term'] = $a_tax_query['terms'][0]; | |
else | |
$q['term_id'] = $a_tax_query['terms'][0]; | |
break; | |
} | |
} | |
} | |
$cat_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'category' ) ); | |
if ( ! empty( $cat_query ) ) { | |
$cat_query = reset( $cat_query ); | |
if ( ! empty( $cat_query['terms'][0] ) ) { | |
$the_cat = get_term_by( $cat_query['field'], $cat_query['terms'][0], 'category' ); | |
if ( $the_cat ) { | |
$this->set( 'cat', $the_cat->term_id ); | |
$this->set( 'category_name', $the_cat->slug ); | |
} | |
unset( $the_cat ); | |
} | |
} | |
unset( $cat_query ); | |
$tag_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'post_tag' ) ); | |
if ( ! empty( $tag_query ) ) { | |
$tag_query = reset( $tag_query ); | |
if ( ! empty( $tag_query['terms'][0] ) ) { | |
$the_tag = get_term_by( $tag_query['field'], $tag_query['terms'][0], 'post_tag' ); | |
if ( $the_tag ) | |
$this->set( 'tag_id', $the_tag->term_id ); | |
unset( $the_tag ); | |
} | |
} | |
unset( $tag_query ); | |
} | |
} | |
if ( !empty( $this->tax_query->queries ) || !empty( $this->meta_query->queries ) ) { | |
$groupby = "{$wpdb->posts}.ID"; | |
} | |
// Author/user stuff | |
if ( empty($q['author']) || ($q['author'] == '0') ) { | |
$whichauthor = ''; | |
} else { | |
$q['author'] = (string)urldecode($q['author']); | |
$q['author'] = addslashes_gpc($q['author']); | |
if ( strpos($q['author'], '-') !== false ) { | |
$eq = '!='; | |
$andor = 'AND'; | |
$q['author'] = explode('-', $q['author']); | |
$q['author'] = (string)absint($q['author'][1]); | |
} else { | |
$eq = '='; | |
$andor = 'OR'; | |
} | |
$author_array = preg_split('/[,\s]+/', $q['author']); | |
$_author_array = array(); | |
foreach ( $author_array as $key => $_author ) | |
$_author_array[] = "$wpdb->posts.post_author " . $eq . ' ' . absint($_author); | |
$whichauthor .= ' AND (' . implode(" $andor ", $_author_array) . ')'; | |
unset($author_array, $_author_array); | |
} | |
// Author stuff for nice URLs | |
if ( '' != $q['author_name'] ) { | |
if ( strpos($q['author_name'], '/') !== false ) { | |
$q['author_name'] = explode('/', $q['author_name']); | |
if ( $q['author_name'][ count($q['author_name'])-1 ] ) { | |
$q['author_name'] = $q['author_name'][count($q['author_name'])-1]; // no trailing slash | |
} else { | |
$q['author_name'] = $q['author_name'][count($q['author_name'])-2]; // there was a trailing slash | |
} | |
} | |
$q['author_name'] = sanitize_title_for_query( $q['author_name'] ); | |
$q['author'] = get_user_by('slug', $q['author_name']); | |
if ( $q['author'] ) | |
$q['author'] = $q['author']->ID; | |
$whichauthor .= " AND ($wpdb->posts.post_author = " . absint($q['author']) . ')'; | |
} | |
// MIME-Type stuff for attachment browsing | |
if ( isset( $q['post_mime_type'] ) && '' != $q['post_mime_type'] ) | |
$whichmimetype = wp_post_mime_type_where( $q['post_mime_type'], $wpdb->posts ); | |
$where .= $search . $whichauthor . $whichmimetype; | |
if ( empty($q['order']) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC')) ) | |
$q['order'] = 'DESC'; | |
// Order by | |
if ( empty($q['orderby']) ) { | |
$orderby = "$wpdb->posts.post_date " . $q['order']; | |
} elseif ( 'none' == $q['orderby'] ) { | |
$orderby = ''; | |
} elseif ( $q['orderby'] == 'post__in' && ! empty( $post__in ) ) { | |
$orderby = "FIELD( {$wpdb->posts}.ID, $post__in )"; | |
} elseif ( $q['orderby'] == 'post_parent__in' && ! empty( $post_parent__in ) ) { | |
$orderby = "FIELD( {$wpdb->posts}.post_parent, $post_parent__in )"; | |
} else { | |
// Used to filter values | |
$allowed_keys = array('name', 'author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count'); | |
if ( !empty($q['meta_key']) ) { | |
$allowed_keys[] = $q['meta_key']; | |
$allowed_keys[] = 'meta_value'; | |
$allowed_keys[] = 'meta_value_num'; | |
} | |
$q['orderby'] = urldecode($q['orderby']); | |
$q['orderby'] = addslashes_gpc($q['orderby']); | |
$orderby_array = array(); | |
foreach ( explode( ' ', $q['orderby'] ) as $i => $orderby ) { | |
// Only allow certain values for safety | |
if ( ! in_array($orderby, $allowed_keys) ) | |
continue; | |
switch ( $orderby ) { | |
case 'menu_order': | |
$orderby = "$wpdb->posts.menu_order"; | |
break; | |
case 'ID': | |
$orderby = "$wpdb->posts.ID"; | |
break; | |
case 'rand': | |
$orderby = 'RAND()'; | |
break; | |
case $q['meta_key']: | |
case 'meta_value': | |
$orderby = "$wpdb->postmeta.meta_value"; | |
break; | |
case 'meta_value_num': | |
$orderby = "$wpdb->postmeta.meta_value+0"; | |
break; | |
case 'comment_count': | |
$orderby = "$wpdb->posts.comment_count"; | |
break; | |
default: | |
$orderby = "$wpdb->posts.post_" . $orderby; | |
} | |
$orderby_array[] = $orderby; | |
} | |
$orderby = implode( ',', $orderby_array ); | |
if ( empty( $orderby ) ) | |
$orderby = "$wpdb->posts.post_date ".$q['order']; | |
else | |
$orderby .= " {$q['order']}"; | |
} | |
if ( is_array( $post_type ) && count( $post_type ) > 1 ) { | |
$post_type_cap = 'multiple_post_type'; | |
} else { | |
if ( is_array( $post_type ) ) | |
$post_type = reset( $post_type ); | |
$post_type_object = get_post_type_object( $post_type ); | |
if ( empty( $post_type_object ) ) | |
$post_type_cap = $post_type; | |
} | |
if ( 'any' == $post_type ) { | |
$in_search_post_types = get_post_types( array('exclude_from_search' => false) ); | |
if ( ! empty( $in_search_post_types ) ) | |
$where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $in_search_post_types ) . "')"; | |
} elseif ( !empty( $post_type ) && is_array( $post_type ) ) { | |
$where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $post_type) . "')"; | |
} elseif ( ! empty( $post_type ) ) { | |
$where .= " AND $wpdb->posts.post_type = '$post_type'"; | |
$post_type_object = get_post_type_object ( $post_type ); | |
} elseif ( $this->is_attachment ) { | |
$where .= " AND $wpdb->posts.post_type = 'attachment'"; | |
$post_type_object = get_post_type_object ( 'attachment' ); | |
} elseif ( $this->is_page ) { | |
$where .= " AND $wpdb->posts.post_type = 'page'"; | |
$post_type_object = get_post_type_object ( 'page' ); | |
} else { | |
$where .= " AND $wpdb->posts.post_type = 'post'"; | |
$post_type_object = get_post_type_object ( 'post' ); | |
} | |
$edit_cap = 'edit_post'; | |
$read_cap = 'read_post'; | |
if ( ! empty( $post_type_object ) ) { | |
$edit_others_cap = $post_type_object->cap->edit_others_posts; | |
$read_private_cap = $post_type_object->cap->read_private_posts; | |
} else { | |
$edit_others_cap = 'edit_others_' . $post_type_cap . 's'; | |
$read_private_cap = 'read_private_' . $post_type_cap . 's'; | |
} | |
if ( ! empty( $q['post_status'] ) ) { | |
$statuswheres = array(); | |
$q_status = $q['post_status']; | |
if ( ! is_array( $q_status ) ) | |
$q_status = explode(',', $q_status); | |
$r_status = array(); | |
$p_status = array(); | |
$e_status = array(); | |
if ( in_array('any', $q_status) ) { | |
foreach ( get_post_stati( array('exclude_from_search' => true) ) as $status ) | |
$e_status[] = "$wpdb->posts.post_status <> '$status'"; | |
} else { | |
foreach ( get_post_stati() as $status ) { | |
if ( in_array( $status, $q_status ) ) { | |
if ( 'private' == $status ) | |
$p_status[] = "$wpdb->posts.post_status = '$status'"; | |
else | |
$r_status[] = "$wpdb->posts.post_status = '$status'"; | |
} | |
} | |
} | |
if ( empty($q['perm'] ) || 'readable' != $q['perm'] ) { | |
$r_status = array_merge($r_status, $p_status); | |
unset($p_status); | |
} | |
if ( !empty($e_status) ) { | |
$statuswheres[] = "(" . join( ' AND ', $e_status ) . ")"; | |
} | |
if ( !empty($r_status) ) { | |
if ( !empty($q['perm'] ) && 'editable' == $q['perm'] && !current_user_can($edit_others_cap) ) | |
$statuswheres[] = "($wpdb->posts.post_author = $user_ID " . "AND (" . join( ' OR ', $r_status ) . "))"; | |
else | |
$statuswheres[] = "(" . join( ' OR ', $r_status ) . ")"; | |
} | |
if ( !empty($p_status) ) { | |
if ( !empty($q['perm'] ) && 'readable' == $q['perm'] && !current_user_can($read_private_cap) ) | |
$statuswheres[] = "($wpdb->posts.post_author = $user_ID " . "AND (" . join( ' OR ', $p_status ) . "))"; | |
else | |
$statuswheres[] = "(" . join( ' OR ', $p_status ) . ")"; | |
} | |
if ( $post_status_join ) { | |
$join .= " LEFT JOIN $wpdb->posts AS p2 ON ($wpdb->posts.post_parent = p2.ID) "; | |
foreach ( $statuswheres as $index => $statuswhere ) | |
$statuswheres[$index] = "($statuswhere OR ($wpdb->posts.post_status = 'inherit' AND " . str_replace($wpdb->posts, 'p2', $statuswhere) . "))"; | |
} | |
foreach ( $statuswheres as $statuswhere ) | |
$where .= " AND $statuswhere"; | |
} elseif ( !$this->is_singular ) { | |
$where .= " AND ($wpdb->posts.post_status = 'publish'"; | |
// Add public states. | |
$public_states = get_post_stati( array('public' => true) ); | |
foreach ( (array) $public_states as $state ) { | |
if ( 'publish' == $state ) // Publish is hard-coded above. | |
continue; | |
$where .= " OR $wpdb->posts.post_status = '$state'"; | |
} | |
if ( $this->is_admin ) { | |
// Add protected states that should show in the admin all list. | |
$admin_all_states = get_post_stati( array('protected' => true, 'show_in_admin_all_list' => true) ); | |
foreach ( (array) $admin_all_states as $state ) | |
$where .= " OR $wpdb->posts.post_status = '$state'"; | |
} | |
if ( is_user_logged_in() ) { | |
// Add private states that are limited to viewing by the author of a post or someone who has caps to read private states. | |
$private_states = get_post_stati( array('private' => true) ); | |
foreach ( (array) $private_states as $state ) | |
$where .= current_user_can( $read_private_cap ) ? " OR $wpdb->posts.post_status = '$state'" : " OR $wpdb->posts.post_author = $user_ID AND $wpdb->posts.post_status = '$state'"; | |
} | |
$where .= ')'; | |
} | |
if ( !empty( $this->meta_query->queries ) ) { | |
$clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this ); | |
$join .= $clauses['join']; | |
$where .= $clauses['where']; | |
} | |
// Apply filters on where and join prior to paging so that any | |
// manipulations to them are reflected in the paging by day queries. | |
if ( !$q['suppress_filters'] ) { | |
$where = apply_filters_ref_array('posts_where', array( $where, &$this ) ); | |
$join = apply_filters_ref_array('posts_join', array( $join, &$this ) ); | |
} | |
// Paging | |
if ( empty($q['nopaging']) && !$this->is_singular ) { | |
$page = absint($q['paged']); | |
if ( !$page ) | |
$page = 1; | |
if ( empty($q['offset']) ) { | |
$pgstrt = ($page - 1) * $q['posts_per_page'] . ', '; | |
} else { // we're ignoring $page and using 'offset' | |
$q['offset'] = absint($q['offset']); | |
$pgstrt = $q['offset'] . ', '; | |
} | |
$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page']; | |
} | |
// Comments feeds | |
if ( $this->is_comment_feed && ( $this->is_archive || $this->is_search || !$this->is_singular ) ) { | |
if ( $this->is_archive || $this->is_search ) { | |
$cjoin = "JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) $join "; | |
$cwhere = "WHERE comment_approved = '1' $where"; | |
$cgroupby = "$wpdb->comments.comment_id"; | |
} else { // Other non singular e.g. front | |
$cjoin = "JOIN $wpdb->posts ON ( $wpdb->comments.comment_post_ID = $wpdb->posts.ID )"; | |
$cwhere = "WHERE post_status = 'publish' AND comment_approved = '1'"; | |
$cgroupby = ''; | |
} | |
if ( !$q['suppress_filters'] ) { | |
$cjoin = apply_filters_ref_array('comment_feed_join', array( $cjoin, &$this ) ); | |
$cwhere = apply_filters_ref_array('comment_feed_where', array( $cwhere, &$this ) ); | |
$cgroupby = apply_filters_ref_array('comment_feed_groupby', array( $cgroupby, &$this ) ); | |
$corderby = apply_filters_ref_array('comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) ); | |
$climits = apply_filters_ref_array('comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) ); | |
} | |
$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : ''; | |
$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : ''; | |
$this->comments = (array) $wpdb->get_results("SELECT $distinct $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits"); | |
$this->comment_count = count($this->comments); | |
$post_ids = array(); | |
foreach ( $this->comments as $comment ) | |
$post_ids[] = (int) $comment->comment_post_ID; | |
$post_ids = join(',', $post_ids); | |
$join = ''; | |
if ( $post_ids ) | |
$where = "AND $wpdb->posts.ID IN ($post_ids) "; | |
else | |
$where = "AND 0"; | |
} | |
$pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' ); | |
// Apply post-paging filters on where and join. Only plugins that | |
// manipulate paging queries should use these hooks. | |
if ( !$q['suppress_filters'] ) { | |
$where = apply_filters_ref_array( 'posts_where_paged', array( $where, &$this ) ); | |
$groupby = apply_filters_ref_array( 'posts_groupby', array( $groupby, &$this ) ); | |
$join = apply_filters_ref_array( 'posts_join_paged', array( $join, &$this ) ); | |
$orderby = apply_filters_ref_array( 'posts_orderby', array( $orderby, &$this ) ); | |
$distinct = apply_filters_ref_array( 'posts_distinct', array( $distinct, &$this ) ); | |
$limits = apply_filters_ref_array( 'post_limits', array( $limits, &$this ) ); | |
$fields = apply_filters_ref_array( 'posts_fields', array( $fields, &$this ) ); | |
// Filter all clauses at once, for convenience | |
$clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) ); | |
foreach ( $pieces as $piece ) | |
$$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : ''; | |
} | |
// Announce current selection parameters. For use by caching plugins. | |
do_action( 'posts_selection', $where . $groupby . $orderby . $limits . $join ); | |
// Filter again for the benefit of caching plugins. Regular plugins should use the hooks above. | |
if ( !$q['suppress_filters'] ) { | |
$where = apply_filters_ref_array( 'posts_where_request', array( $where, &$this ) ); | |
$groupby = apply_filters_ref_array( 'posts_groupby_request', array( $groupby, &$this ) ); | |
$join = apply_filters_ref_array( 'posts_join_request', array( $join, &$this ) ); | |
$orderby = apply_filters_ref_array( 'posts_orderby_request', array( $orderby, &$this ) ); | |
$distinct = apply_filters_ref_array( 'posts_distinct_request', array( $distinct, &$this ) ); | |
$fields = apply_filters_ref_array( 'posts_fields_request', array( $fields, &$this ) ); | |
$limits = apply_filters_ref_array( 'post_limits_request', array( $limits, &$this ) ); | |
// Filter all clauses at once, for convenience | |
$clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) ); | |
foreach ( $pieces as $piece ) | |
$$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : ''; | |
} | |
if ( ! empty($groupby) ) | |
$groupby = 'GROUP BY ' . $groupby; | |
if ( !empty( $orderby ) ) | |
$orderby = 'ORDER BY ' . $orderby; | |
$found_rows = ''; | |
if ( !$q['no_found_rows'] && !empty($limits) ) | |
$found_rows = 'SQL_CALC_FOUND_ROWS'; | |
$this->request = $old_request = "SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits"; | |
if ( !$q['suppress_filters'] ) { | |
$this->request = apply_filters_ref_array( 'posts_request', array( $this->request, &$this ) ); | |
} | |
if ( 'ids' == $q['fields'] ) { | |
$this->posts = $wpdb->get_col( $this->request ); | |
$this->post_count = count( $this->posts ); | |
$this->set_found_posts( $q, $limits ); | |
return $this->posts; | |
} | |
if ( 'id=>parent' == $q['fields'] ) { | |
$this->posts = $wpdb->get_results( $this->request ); | |
$this->post_count = count( $this->posts ); | |
$this->set_found_posts( $q, $limits ); | |
$r = array(); | |
foreach ( $this->posts as $post ) | |
$r[ $post->ID ] = $post->post_parent; | |
return $r; | |
} | |
$split_the_query = ( $old_request == $this->request && "$wpdb->posts.*" == $fields && !empty( $limits ) && $q['posts_per_page'] < 500 ); | |
$split_the_query = apply_filters( 'split_the_query', $split_the_query, $this ); | |
if ( $split_the_query ) { | |
// First get the IDs and then fill in the objects | |
$this->request = "SELECT $found_rows $distinct $wpdb->posts.ID FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits"; | |
$this->request = apply_filters( 'posts_request_ids', $this->request, $this ); | |
$ids = $wpdb->get_col( $this->request ); | |
if ( $ids ) { | |
$this->posts = $ids; | |
$this->set_found_posts( $q, $limits ); | |
_prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] ); | |
} else { | |
$this->posts = array(); | |
} | |
} else { | |
$this->posts = $wpdb->get_results( $this->request ); | |
$this->set_found_posts( $q, $limits ); | |
} | |
// Convert to WP_Post objects | |
if ( $this->posts ) | |
$this->posts = array_map( 'get_post', $this->posts ); | |
// Raw results filter. Prior to status checks. | |
if ( !$q['suppress_filters'] ) | |
$this->posts = apply_filters_ref_array('posts_results', array( $this->posts, &$this ) ); | |
if ( !empty($this->posts) && $this->is_comment_feed && $this->is_singular ) { | |
$cjoin = apply_filters_ref_array('comment_feed_join', array( '', &$this ) ); | |
$cwhere = apply_filters_ref_array('comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) ); | |
$cgroupby = apply_filters_ref_array('comment_feed_groupby', array( '', &$this ) ); | |
$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : ''; | |
$corderby = apply_filters_ref_array('comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) ); | |
$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : ''; | |
$climits = apply_filters_ref_array('comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) ); | |
$comments_request = "SELECT $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits"; | |
$this->comments = $wpdb->get_results($comments_request); | |
$this->comment_count = count($this->comments); | |
} | |
// Check post status to determine if post should be displayed. | |
if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) { | |
$status = get_post_status($this->posts[0]); | |
$post_status_obj = get_post_status_object($status); | |
//$type = get_post_type($this->posts[0]); | |
if ( !$post_status_obj->public ) { | |
if ( ! is_user_logged_in() ) { | |
// User must be logged in to view unpublished posts. | |
$this->posts = array(); | |
} else { | |
if ( $post_status_obj->protected ) { | |
// User must have edit permissions on the draft to preview. | |
if ( ! current_user_can($edit_cap, $this->posts[0]->ID) ) { | |
$this->posts = array(); | |
} else { | |
$this->is_preview = true; | |
if ( 'future' != $status ) | |
$this->posts[0]->post_date = current_time('mysql'); | |
} | |
} elseif ( $post_status_obj->private ) { | |
if ( ! current_user_can($read_cap, $this->posts[0]->ID) ) | |
$this->posts = array(); | |
} else { | |
$this->posts = array(); | |
} | |
} | |
} | |
if ( $this->is_preview && $this->posts && current_user_can( $edit_cap, $this->posts[0]->ID ) ) | |
$this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) ); | |
} | |
// Put sticky posts at the top of the posts array | |
$sticky_posts = get_option('sticky_posts'); | |
if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) { | |
$num_posts = count($this->posts); | |
$sticky_offset = 0; | |
// Loop over posts and relocate stickies to the front. | |
for ( $i = 0; $i < $num_posts; $i++ ) { | |
if ( in_array($this->posts[$i]->ID, $sticky_posts) ) { | |
$sticky_post = $this->posts[$i]; | |
// Remove sticky from current position | |
array_splice($this->posts, $i, 1); | |
// Move to front, after other stickies | |
array_splice($this->posts, $sticky_offset, 0, array($sticky_post)); | |
// Increment the sticky offset. The next sticky will be placed at this offset. | |
$sticky_offset++; | |
// Remove post from sticky posts array | |
$offset = array_search($sticky_post->ID, $sticky_posts); | |
unset( $sticky_posts[$offset] ); | |
} | |
} | |
// If any posts have been excluded specifically, Ignore those that are sticky. | |
if ( !empty($sticky_posts) && !empty($q['post__not_in']) ) | |
$sticky_posts = array_diff($sticky_posts, $q['post__not_in']); | |
// Fetch sticky posts that weren't in the query results | |
if ( !empty($sticky_posts) ) { | |
$stickies = get_posts( array( | |
'post__in' => $sticky_posts, | |
'post_type' => $post_type, | |
'post_status' => 'publish', | |
'nopaging' => true | |
) ); | |
foreach ( $stickies as $sticky_post ) { | |
array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) ); | |
$sticky_offset++; | |
} | |
} | |
} | |
if ( !$q['suppress_filters'] ) | |
$this->posts = apply_filters_ref_array('the_posts', array( $this->posts, &$this ) ); | |
// Ensure that any posts added/modified via one of the filters above are | |
// of the type WP_Post and are filtered. | |
if ( $this->posts ) { | |
$this->post_count = count( $this->posts ); | |
$this->posts = array_map( 'get_post', $this->posts ); | |
if ( $q['cache_results'] ) | |
update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']); | |
$this->post = reset( $this->posts ); | |
} else { | |
$this->post_count = 0; | |
$this->posts = array(); | |
} | |
return $this->posts; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment