/** * 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); // 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 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 its 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_page($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 supercede 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']); } 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($q['sentence'])) { $q['search_terms'] = array($q['s']); } else { preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $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 '; } $term = esc_sql(like_escape($q['s'])); if (empty($q['sentence']) && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s']) { $search .= " OR ({$wpdb->posts}.post_title LIKE '{$n}{$term}{$n}') OR ({$wpdb->posts}.post_content LIKE '{$n}{$term}{$n}')"; } 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)) { $post_type = 'any'; $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); $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); $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); } } // 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 trailling 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']) { $table_alias = $post_status_join ? $wpdb->posts : ''; $whichmimetype = wp_post_mime_type_where($q['post_mime_type'], $table_alias); } $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'])) { $q['orderby'] = "{$wpdb->posts}.post_date " . $q['order']; } elseif ('none' == $q['orderby']) { $q['orderby'] = ''; } else { // Used to filter values $allowed_keys = array('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 = explode(' ', $q['orderby']); $q['orderby'] = ''; foreach ($orderby_array as $i => $orderby) { // Only allow certain values for safety if (!in_array($orderby, $allowed_keys)) { continue; } switch ($orderby) { case '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; } $q['orderby'] .= ($i == 0 ? '' : ',') . $orderby; } // append ASC or DESC at the end if (!empty($q['orderby'])) { $q['orderby'] .= " {$q['order']}"; } if (empty($q['orderby'])) { $q['orderby'] = "{$wpdb->posts}.post_date " . $q['order']; } } if (is_array($post_type)) { $post_type_cap = 'multiple_post_type'; } else { $post_type_object = get_post_type_object($post_type); if (empty($post_type_object)) { $post_type_cap = $post_type; } } $exclude_post_types = ''; $in_search_post_types = get_post_types(array('exclude_from_search' => false)); if (!empty($in_search_post_types)) { $exclude_post_types .= $wpdb->prepare(" AND {$wpdb->posts}.post_type IN ('" . join("', '", $in_search_post_types) . "')"); } if ('any' == $post_type) { $where .= $exclude_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'); } if (!empty($post_type_object)) { $edit_cap = $post_type_object->cap->edit_post; $read_cap = $post_type_object->cap->read_post; $edit_others_cap = $post_type_object->cap->edit_others_posts; $read_private_cap = $post_type_object->cap->read_private_posts; } else { $edit_cap = 'edit_' . $post_type_cap; $read_cap = 'read_' . $post_type_cap; $edit_others_cap = 'edit_others_' . $post_type_cap . 's'; $read_private_cap = 'read_private_' . $post_type_cap . 's'; } if (isset($q['post_status']) && '' != $q['post_status']) { $statuswheres = array(); $q_status = explode(',', $q['post_status']); $r_status = array(); $p_status = array(); $e_status = array(); if ($q['post_status'] == 'any') { 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 (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 .= ')'; } // Parse the meta query again if query vars have changed. if ($this->query_vars_changed) { $meta_query_hash = md5(serialize($q['meta_query'])); $_meta_query = $q['meta_query']; unset($q['meta_query']); _parse_meta_query($q); if (md5(serialize($q['meta_query'])) != $meta_query_hash && is_array($_meta_query)) { $q['meta_query'] = array_merge($_meta_query, $q['meta_query']); } } if (!empty($q['meta_query'])) { $clauses = call_user_func_array('_get_meta_sql', array($q['meta_query'], 'post', $wpdb->posts, 'ID', &$this)); $join .= $clauses['join']; $where .= $clauses['where']; } if (!empty($this->tax_query->queries) || !empty($q['meta_query'])) { $groupby = "{$wpdb->posts}.ID"; } // 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 (empty($page)) { $page = 1; } if (empty($q['offset'])) { $pgstrt = ''; $pgstrt = ($page - 1) * $q['posts_per_page'] . ', '; $limits = 'LIMIT ' . $pgstrt . $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"; } } $orderby = $q['orderby']; $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 = " 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); return $this->posts; } if ('id=>parent' == $q['fields']) { $this->posts = $wpdb->get_results($this->request); $r = array(); foreach ($this->posts as $post) { $r[$post->ID] = $post->post_parent; } return $r; } $this->posts = $wpdb->get_results($this->request); // 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); } if (!$q['no_found_rows'] && !empty($limits)) { $found_posts_query = apply_filters_ref_array('found_posts_query', array('SELECT FOUND_ROWS()', &$this)); $this->found_posts = $wpdb->get_var($found_posts_query); $this->found_posts = apply_filters_ref_array('found_posts', array($this->found_posts, &$this)); $this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']); } // 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 && current_user_can($edit_cap, $this->posts[0]->ID)) { $this->posts[0] = 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__in = implode(',', array_map('absint', $sticky_posts)); // honor post type(s) if not set to any $stickies_where = ''; if ('any' != $post_type && '' != $post_type) { if (is_array($post_type)) { $post_types = join("', '", $post_type); } else { $post_types = $post_type; } $stickies_where = "AND {$wpdb->posts}.post_type IN ('" . $post_types . "')"; } $stickies = $wpdb->get_results("SELECT * FROM {$wpdb->posts} WHERE {$wpdb->posts}.ID IN ({$stickies__in}) {$stickies_where}"); foreach ($stickies as $sticky_post) { // Ignore sticky posts the current user cannot read or are not published. if ('publish' != $sticky_post->post_status) { continue; } 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)); } $this->post_count = count($this->posts); // Sanitize before caching so it'll only get done once for ($i = 0; $i < $this->post_count; $i++) { $this->posts[$i] = sanitize_post($this->posts[$i], 'raw'); } if ($q['cache_results']) { update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']); } if ($this->post_count > 0) { $this->post = $this->posts[0]; } return $this->posts; }
/** * Parse a query string and set query type booleans. * * @since 1.5.0 * @access public * * @param string|array $query Optional query. */ function parse_query($query = '') { if (!empty($query)) { $this->init(); $this->query = $this->query_vars = wp_parse_args($query); } elseif (!isset($this->query)) { $this->query = $this->query_vars; } $this->query_vars = $this->fill_query_vars($this->query_vars); $qv =& $this->query_vars; if (!empty($qv['robots'])) { $this->is_robots = true; } $qv['p'] = absint($qv['p']); $qv['page_id'] = absint($qv['page_id']); $qv['year'] = absint($qv['year']); $qv['monthnum'] = absint($qv['monthnum']); $qv['day'] = absint($qv['day']); $qv['w'] = absint($qv['w']); $qv['m'] = absint($qv['m']); $qv['paged'] = absint($qv['paged']); $qv['cat'] = preg_replace('|[^0-9,-]|', '', $qv['cat']); // comma separated list of positive or negative integers $qv['pagename'] = trim($qv['pagename']); $qv['name'] = trim($qv['name']); if ('' !== $qv['hour']) { $qv['hour'] = absint($qv['hour']); } if ('' !== $qv['minute']) { $qv['minute'] = absint($qv['minute']); } if ('' !== $qv['second']) { $qv['second'] = absint($qv['second']); } // Compat. Map subpost to attachment. if ('' != $qv['subpost']) { $qv['attachment'] = $qv['subpost']; } if ('' != $qv['subpost_id']) { $qv['attachment_id'] = $qv['subpost_id']; } $qv['attachment_id'] = absint($qv['attachment_id']); if ('' != $qv['attachment'] || !empty($qv['attachment_id'])) { $this->is_single = true; $this->is_attachment = true; } elseif ('' != $qv['name']) { $this->is_single = true; } elseif ($qv['p']) { $this->is_single = true; } elseif ('' !== $qv['hour'] && '' !== $qv['minute'] && '' !== $qv['second'] && '' != $qv['year'] && '' != $qv['monthnum'] && '' != $qv['day']) { // If year, month, day, hour, minute, and second are set, a single // post is being queried. $this->is_single = true; } elseif ('' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id'])) { $this->is_page = true; $this->is_single = false; } else { // Look for archive queries. Dates, categories, authors, search, post type archives. if (!empty($qv['s'])) { $this->is_search = true; } if ('' !== $qv['second']) { $this->is_time = true; $this->is_date = true; } if ('' !== $qv['minute']) { $this->is_time = true; $this->is_date = true; } if ('' !== $qv['hour']) { $this->is_time = true; $this->is_date = true; } if ($qv['day']) { if (!$this->is_date) { $this->is_day = true; $this->is_date = true; } } if ($qv['monthnum']) { if (!$this->is_date) { $this->is_month = true; $this->is_date = true; } } if ($qv['year']) { if (!$this->is_date) { $this->is_year = true; $this->is_date = true; } } if ($qv['m']) { $this->is_date = true; if (strlen($qv['m']) > 9) { $this->is_time = true; } else { if (strlen($qv['m']) > 7) { $this->is_day = true; } else { if (strlen($qv['m']) > 5) { $this->is_month = true; } else { $this->is_year = true; } } } } if ('' != $qv['w']) { $this->is_date = true; } $this->parsed_tax_query = false; $this->parse_tax_query($qv); foreach ($this->tax_query->queries as $tax_query) { if ('IN' == $tax_query['operator']) { switch ($tax_query['taxonomy']) { case 'category': $this->is_category = true; break; case 'post_tag': $this->is_tag = true; break; default: $this->is_tax = true; } } } unset($tax_query); _parse_meta_query($qv); if (empty($qv['author']) || $qv['author'] == '0') { $this->is_author = false; } else { $this->is_author = true; } if ('' != $qv['author_name']) { $this->is_author = true; } if (!empty($qv['post_type']) && !is_array($qv['post_type'])) { $post_type_obj = get_post_type_object($qv['post_type']); if (!empty($post_type_obj->has_archive)) { $this->is_post_type_archive = true; } } if ($this->is_post_type_archive || $this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax) { $this->is_archive = true; } } if ('' != $qv['feed']) { $this->is_feed = true; } if ('' != $qv['tb']) { $this->is_trackback = true; } if ('' != $qv['paged'] && intval($qv['paged']) > 1) { $this->is_paged = true; } if ('' != $qv['comments_popup']) { $this->is_comments_popup = true; } // if we're previewing inside the write screen if ('' != $qv['preview']) { $this->is_preview = true; } if (is_admin()) { $this->is_admin = true; } if (false !== strpos($qv['feed'], 'comments-')) { $qv['feed'] = str_replace('comments-', '', $qv['feed']); $qv['withcomments'] = 1; } $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment; if ($this->is_feed && (!empty($qv['withcomments']) || empty($qv['withoutcomments']) && $this->is_singular)) { $this->is_comment_feed = true; } if (!($this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_comments_popup || $this->is_robots)) { $this->is_home = true; } // Correct is_* for page_on_front and page_for_posts if ($this->is_home && 'page' == get_option('show_on_front') && get_option('page_on_front')) { $_query = wp_parse_args($this->query); // pagename can be set and empty depending on matched rewrite rules. Ignore an empty pagename. if (isset($_query['pagename']) && '' == $_query['pagename']) { unset($_query['pagename']); } if (empty($_query) || !array_diff(array_keys($_query), array('preview', 'page', 'paged', 'cpage'))) { $this->is_page = true; $this->is_home = false; $qv['page_id'] = get_option('page_on_front'); // Correct <!--nextpage--> for page_on_front if (!empty($qv['paged'])) { $qv['page'] = $qv['paged']; unset($qv['paged']); } } } if ('' != $qv['pagename']) { $this->queried_object =& get_page_by_path($qv['pagename']); if (!empty($this->queried_object)) { $this->queried_object_id = (int) $this->queried_object->ID; } else { unset($this->queried_object); } if ('page' == get_option('show_on_front') && isset($this->queried_object_id) && $this->queried_object_id == get_option('page_for_posts')) { $this->is_page = false; $this->is_home = true; $this->is_posts_page = true; } } if ($qv['page_id']) { if ('page' == get_option('show_on_front') && $qv['page_id'] == get_option('page_for_posts')) { $this->is_page = false; $this->is_home = true; $this->is_posts_page = true; } } if (!empty($qv['post_type'])) { if (is_array($qv['post_type'])) { $qv['post_type'] = array_map('sanitize_key', $qv['post_type']); } else { $qv['post_type'] = sanitize_key($qv['post_type']); } } if (!empty($qv['post_status'])) { $qv['post_status'] = preg_replace('|[^a-z0-9_,-]|', '', $qv['post_status']); } if ($this->is_posts_page && (!isset($qv['withcomments']) || !$qv['withcomments'])) { $this->is_comment_feed = false; } $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment; // Done correcting is_* for page_on_front and page_for_posts if ('404' == $qv['error']) { $this->set_404(); } do_action_ref_array('parse_query', array(&$this)); }
/** * Prepare the query variables * * @since 3.1.0 * @access private */ function prepare_query() { global $wpdb; $qv =& $this->query_vars; if (is_array($qv['fields'])) { $qv['fields'] = array_unique($qv['fields']); $this->query_fields = array(); foreach ($qv['fields'] as $field) { $this->query_fields[] = $wpdb->users . '.' . esc_sql($field); } $this->query_fields = implode(',', $this->query_fields); } elseif ('all' == $qv['fields']) { $this->query_fields = "{$wpdb->users}.*"; } else { $this->query_fields = "{$wpdb->users}.ID"; } $this->query_from = "FROM {$wpdb->users}"; $this->query_where = "WHERE 1=1"; // sorting if (in_array($qv['orderby'], array('nicename', 'email', 'url', 'registered'))) { $orderby = 'user_' . $qv['orderby']; } elseif (in_array($qv['orderby'], array('user_nicename', 'user_email', 'user_url', 'user_registered'))) { $orderby = $qv['orderby']; } elseif ('name' == $qv['orderby'] || 'display_name' == $qv['orderby']) { $orderby = 'display_name'; } elseif ('post_count' == $qv['orderby']) { // todo: avoid the JOIN $where = get_posts_by_author_sql('post'); $this->query_from .= " LEFT OUTER JOIN (\n\t\t\t\tSELECT post_author, COUNT(*) as post_count\n\t\t\t\tFROM {$wpdb->posts}\n\t\t\t\t{$where}\n\t\t\t\tGROUP BY post_author\n\t\t\t) p ON ({$wpdb->users}.ID = p.post_author)\n\t\t\t"; $orderby = 'post_count'; } elseif ('ID' == $qv['orderby'] || 'id' == $qv['orderby']) { $orderby = 'ID'; } else { $orderby = 'user_login'; } $qv['order'] = strtoupper($qv['order']); if ('ASC' == $qv['order']) { $order = 'ASC'; } else { $order = 'DESC'; } $this->query_orderby = "ORDER BY {$orderby} {$order}"; // limit if ($qv['number']) { if ($qv['offset']) { $this->query_limit = $wpdb->prepare("LIMIT %d, %d", $qv['offset'], $qv['number']); } else { $this->query_limit = $wpdb->prepare("LIMIT %d", $qv['number']); } } $search = trim($qv['search']); if ($search) { $leading_wild = ltrim($search, '*') != $search; $trailing_wild = rtrim($search, '*') != $search; if ($leading_wild && $trailing_wild) { $wild = 'both'; } elseif ($leading_wild) { $wild = 'leading'; } elseif ($trailing_wild) { $wild = 'trailing'; } else { $wild = false; } if ($wild) { $search = trim($search, '*'); } if (false !== strpos($search, '@')) { $search_columns = array('user_email'); } elseif (is_numeric($search)) { $search_columns = array('user_login', 'ID'); } elseif (preg_match('|^https?://|', $search)) { $search_columns = array('user_url'); } else { $search_columns = array('user_login', 'user_nicename'); } $this->query_where .= $this->get_search_sql($search, $search_columns, $wild); } $blog_id = absint($qv['blog_id']); if ('authors' == $qv['who'] && $blog_id) { $qv['meta_key'] = $wpdb->get_blog_prefix($blog_id) . 'user_level'; $qv['meta_value'] = '_wp_zero_value'; // Hack to pass '0' $qv['meta_compare'] = '!='; $qv['blog_id'] = $blog_id = 0; // Prevent extra meta query } _parse_meta_query($qv); $role = trim($qv['role']); if ($blog_id && ($role || is_multisite())) { $cap_meta_query = array(); $cap_meta_query['key'] = $wpdb->get_blog_prefix($blog_id) . 'capabilities'; if ($role) { $cap_meta_query['value'] = '"' . $role . '"'; $cap_meta_query['compare'] = 'like'; } $qv['meta_query'][] = $cap_meta_query; } if (!empty($qv['meta_query'])) { $clauses = call_user_func_array('_get_meta_sql', array($qv['meta_query'], 'user', $wpdb->users, 'ID', &$this)); $this->query_from .= $clauses['join']; $this->query_where .= $clauses['where']; } if (!empty($qv['include'])) { $ids = implode(',', wp_parse_id_list($qv['include'])); $this->query_where .= " AND {$wpdb->users}.ID IN ({$ids})"; } elseif (!empty($qv['exclude'])) { $ids = implode(',', wp_parse_id_list($qv['exclude'])); $this->query_where .= " AND {$wpdb->users}.ID NOT IN ({$ids})"; } do_action_ref_array('pre_user_query', array(&$this)); }