wp/wp-includes/query.php
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
4:346c88efed21 5:5e2f62d02dcd
     3  * WordPress Query API
     3  * WordPress Query API
     4  *
     4  *
     5  * The query API attempts to get which part of WordPress the user is on. It
     5  * The query API attempts to get which part of WordPress the user is on. It
     6  * also provides functionality for getting URL query information.
     6  * also provides functionality for getting URL query information.
     7  *
     7  *
     8  * @link http://codex.wordpress.org/The_Loop More information on The Loop.
     8  * @link https://codex.wordpress.org/The_Loop More information on The Loop.
     9  *
     9  *
    10  * @package WordPress
    10  * @package WordPress
    11  * @subpackage Query
    11  * @subpackage Query
    12  */
    12  */
    13 
    13 
    16  *
    16  *
    17  * @see WP_Query::get()
    17  * @see WP_Query::get()
    18  * @since 1.5.0
    18  * @since 1.5.0
    19  * @uses $wp_query
    19  * @uses $wp_query
    20  *
    20  *
    21  * @param string $var The variable key to retrieve.
    21  * @param string $var       The variable key to retrieve.
       
    22  * @param mixed  $default   Value to return if the query variable is not set. Default ''.
    22  * @return mixed
    23  * @return mixed
    23  */
    24  */
    24 function get_query_var($var) {
    25 function get_query_var( $var, $default = '' ) {
    25 	global $wp_query;
    26 	global $wp_query;
    26 
    27 
    27 	return $wp_query->get($var);
    28 	return $wp_query->get( $var, $default );
    28 }
    29 }
    29 
    30 
    30 /**
    31 /**
    31  * Retrieve the currently-queried object. Wrapper for $wp_query->get_queried_object()
    32  * Retrieve the currently-queried object. Wrapper for $wp_query->get_queried_object()
    32  *
    33  *
   113  * @since 3.0.0
   114  * @since 3.0.0
   114  * @uses $wp_query
   115  * @uses $wp_query
   115  */
   116  */
   116 function wp_reset_postdata() {
   117 function wp_reset_postdata() {
   117 	global $wp_query;
   118 	global $wp_query;
   118 	$wp_query->reset_postdata();
   119 
       
   120 	if ( isset( $wp_query ) ) {
       
   121 		$wp_query->reset_postdata();
       
   122 	}
   119 }
   123 }
   120 
   124 
   121 /*
   125 /*
   122  * Query type checks.
   126  * Query type checks.
   123  */
   127  */
   170  *
   174  *
   171  * @see WP_Query::is_attachment()
   175  * @see WP_Query::is_attachment()
   172  * @since 2.0.0
   176  * @since 2.0.0
   173  * @uses $wp_query
   177  * @uses $wp_query
   174  *
   178  *
       
   179  * @param int|string|array|object $attachment Attachment ID, title, slug, or array of such.
   175  * @return bool
   180  * @return bool
   176  */
   181  */
   177 function is_attachment() {
   182 function is_attachment( $attachment = '' ) {
   178 	global $wp_query;
   183 	global $wp_query;
   179 
   184 
   180 	if ( ! isset( $wp_query ) ) {
   185 	if ( ! isset( $wp_query ) ) {
   181 		_doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
   186 		_doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
   182 		return false;
   187 		return false;
   183 	}
   188 	}
   184 
   189 
   185 	return $wp_query->is_attachment();
   190 	return $wp_query->is_attachment( $attachment );
   186 }
   191 }
   187 
   192 
   188 /**
   193 /**
   189  * Is the query for an existing author archive page?
   194  * Is the query for an existing author archive page?
   190  *
   195  *
   269  *
   274  *
   270  * @see WP_Query::is_tax()
   275  * @see WP_Query::is_tax()
   271  * @since 2.5.0
   276  * @since 2.5.0
   272  * @uses $wp_query
   277  * @uses $wp_query
   273  *
   278  *
   274  * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
   279  * @param string|array $taxonomy Optional. Taxonomy slug or slugs.
   275  * @param mixed $term Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
   280  * @param int|string|array $term Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
   276  * @return bool
   281  * @return bool
   277  */
   282  */
   278 function is_tax( $taxonomy = '', $term = '' ) {
   283 function is_tax( $taxonomy = '', $term = '' ) {
   279 	global $wp_query;
   284 	global $wp_query;
   280 
   285 
   399  *
   404  *
   400  * Otherwise the same as @see is_home()
   405  * Otherwise the same as @see is_home()
   401  *
   406  *
   402  * @see WP_Query::is_front_page()
   407  * @see WP_Query::is_front_page()
   403  * @since 2.5.0
   408  * @since 2.5.0
   404  * @uses is_home()
       
   405  * @uses get_option()
       
   406  *
   409  *
   407  * @return bool True, if front of site.
   410  * @return bool True, if front of site.
   408  */
   411  */
   409 function is_front_page() {
   412 function is_front_page() {
   410 	global $wp_query;
   413 	global $wp_query;
   717  * @return bool
   720  * @return bool
   718  */
   721  */
   719 function is_main_query() {
   722 function is_main_query() {
   720 	if ( 'pre_get_posts' === current_filter() ) {
   723 	if ( 'pre_get_posts' === current_filter() ) {
   721 		$message = sprintf( __( 'In <code>%1$s</code>, use the <code>%2$s</code> method, not the <code>%3$s</code> function. See %4$s.' ),
   724 		$message = sprintf( __( 'In <code>%1$s</code>, use the <code>%2$s</code> method, not the <code>%3$s</code> function. See %4$s.' ),
   722 			'pre_get_posts', 'WP_Query::is_main_query()', 'is_main_query()', __( 'http://codex.wordpress.org/Function_Reference/is_main_query' ) );
   725 			'pre_get_posts', 'WP_Query::is_main_query()', 'is_main_query()', __( 'https://codex.wordpress.org/Function_Reference/is_main_query' ) );
   723 		_doing_it_wrong( __FUNCTION__, $message, '3.7' );
   726 		_doing_it_wrong( __FUNCTION__, $message, '3.7' );
   724 	}
   727 	}
   725 
   728 
   726 	global $wp_query;
   729 	global $wp_query;
   727 	return $wp_query->is_main_query();
   730 	return $wp_query->is_main_query();
   825  */
   828  */
   826 
   829 
   827 /**
   830 /**
   828  * The WordPress Query class.
   831  * The WordPress Query class.
   829  *
   832  *
   830  * @link http://codex.wordpress.org/Function_Reference/WP_Query Codex page.
   833  * @link https://codex.wordpress.org/Function_Reference/WP_Query Codex page.
   831  *
   834  *
   832  * @since 1.5.0
   835  * @since 1.5.0
   833  */
   836  */
   834 class WP_Query {
   837 class WP_Query {
   835 
   838 
   838 	 *
   841 	 *
   839 	 * @since 1.5.0
   842 	 * @since 1.5.0
   840 	 * @access public
   843 	 * @access public
   841 	 * @var array
   844 	 * @var array
   842 	 */
   845 	 */
   843 	var $query;
   846 	public $query;
   844 
   847 
   845 	/**
   848 	/**
   846 	 * Query vars, after parsing
   849 	 * Query vars, after parsing
   847 	 *
   850 	 *
   848 	 * @since 1.5.0
   851 	 * @since 1.5.0
   849 	 * @access public
   852 	 * @access public
   850 	 * @var array
   853 	 * @var array
   851 	 */
   854 	 */
   852 	var $query_vars = array();
   855 	public $query_vars = array();
   853 
   856 
   854 	/**
   857 	/**
   855 	 * Taxonomy query, as passed to get_tax_sql()
   858 	 * Taxonomy query, as passed to get_tax_sql()
   856 	 *
   859 	 *
   857 	 * @since 3.1.0
   860 	 * @since 3.1.0
   858 	 * @access public
   861 	 * @access public
   859 	 * @var object WP_Tax_Query
   862 	 * @var object WP_Tax_Query
   860 	 */
   863 	 */
   861 	var $tax_query;
   864 	public $tax_query;
   862 
   865 
   863 	/**
   866 	/**
   864 	 * Metadata query container
   867 	 * Metadata query container
   865 	 *
   868 	 *
   866 	 * @since 3.2.0
   869 	 * @since 3.2.0
   867 	 * @access public
   870 	 * @access public
   868 	 * @var object WP_Meta_Query
   871 	 * @var object WP_Meta_Query
   869 	 */
   872 	 */
   870 	var $meta_query = false;
   873 	public $meta_query = false;
   871 
   874 
   872 	/**
   875 	/**
   873 	 * Date query container
   876 	 * Date query container
   874 	 *
   877 	 *
   875 	 * @since 3.7.0
   878 	 * @since 3.7.0
   876 	 * @access public
   879 	 * @access public
   877 	 * @var object WP_Date_Query
   880 	 * @var object WP_Date_Query
   878 	 */
   881 	 */
   879 	var $date_query = false;
   882 	public $date_query = false;
   880 
   883 
   881 	/**
   884 	/**
   882 	 * Holds the data for a single object that is queried.
   885 	 * Holds the data for a single object that is queried.
   883 	 *
   886 	 *
   884 	 * Holds the contents of a post, page, category, attachment.
   887 	 * Holds the contents of a post, page, category, attachment.
   885 	 *
   888 	 *
   886 	 * @since 1.5.0
   889 	 * @since 1.5.0
   887 	 * @access public
   890 	 * @access public
   888 	 * @var object|array
   891 	 * @var object|array
   889 	 */
   892 	 */
   890 	var $queried_object;
   893 	public $queried_object;
   891 
   894 
   892 	/**
   895 	/**
   893 	 * The ID of the queried object.
   896 	 * The ID of the queried object.
   894 	 *
   897 	 *
   895 	 * @since 1.5.0
   898 	 * @since 1.5.0
   896 	 * @access public
   899 	 * @access public
   897 	 * @var int
   900 	 * @var int
   898 	 */
   901 	 */
   899 	var $queried_object_id;
   902 	public $queried_object_id;
   900 
   903 
   901 	/**
   904 	/**
   902 	 * Get post database query.
   905 	 * Get post database query.
   903 	 *
   906 	 *
   904 	 * @since 2.0.1
   907 	 * @since 2.0.1
   905 	 * @access public
   908 	 * @access public
   906 	 * @var string
   909 	 * @var string
   907 	 */
   910 	 */
   908 	var $request;
   911 	public $request;
   909 
   912 
   910 	/**
   913 	/**
   911 	 * List of posts.
   914 	 * List of posts.
   912 	 *
   915 	 *
   913 	 * @since 1.5.0
   916 	 * @since 1.5.0
   914 	 * @access public
   917 	 * @access public
   915 	 * @var array
   918 	 * @var array
   916 	 */
   919 	 */
   917 	var $posts;
   920 	public $posts;
   918 
   921 
   919 	/**
   922 	/**
   920 	 * The amount of posts for the current query.
   923 	 * The amount of posts for the current query.
   921 	 *
   924 	 *
   922 	 * @since 1.5.0
   925 	 * @since 1.5.0
   923 	 * @access public
   926 	 * @access public
   924 	 * @var int
   927 	 * @var int
   925 	 */
   928 	 */
   926 	var $post_count = 0;
   929 	public $post_count = 0;
   927 
   930 
   928 	/**
   931 	/**
   929 	 * Index of the current item in the loop.
   932 	 * Index of the current item in the loop.
   930 	 *
   933 	 *
   931 	 * @since 1.5.0
   934 	 * @since 1.5.0
   932 	 * @access public
   935 	 * @access public
   933 	 * @var int
   936 	 * @var int
   934 	 */
   937 	 */
   935 	var $current_post = -1;
   938 	public $current_post = -1;
   936 
   939 
   937 	/**
   940 	/**
   938 	 * Whether the loop has started and the caller is in the loop.
   941 	 * Whether the loop has started and the caller is in the loop.
   939 	 *
   942 	 *
   940 	 * @since 2.0.0
   943 	 * @since 2.0.0
   941 	 * @access public
   944 	 * @access public
   942 	 * @var bool
   945 	 * @var bool
   943 	 */
   946 	 */
   944 	var $in_the_loop = false;
   947 	public $in_the_loop = false;
   945 
   948 
   946 	/**
   949 	/**
   947 	 * The current post.
   950 	 * The current post.
   948 	 *
   951 	 *
   949 	 * @since 1.5.0
   952 	 * @since 1.5.0
   950 	 * @access public
   953 	 * @access public
   951 	 * @var WP_Post
   954 	 * @var WP_Post
   952 	 */
   955 	 */
   953 	var $post;
   956 	public $post;
   954 
   957 
   955 	/**
   958 	/**
   956 	 * The list of comments for current post.
   959 	 * The list of comments for current post.
   957 	 *
   960 	 *
   958 	 * @since 2.2.0
   961 	 * @since 2.2.0
   959 	 * @access public
   962 	 * @access public
   960 	 * @var array
   963 	 * @var array
   961 	 */
   964 	 */
   962 	var $comments;
   965 	public $comments;
   963 
   966 
   964 	/**
   967 	/**
   965 	 * The amount of comments for the posts.
   968 	 * The amount of comments for the posts.
   966 	 *
   969 	 *
   967 	 * @since 2.2.0
   970 	 * @since 2.2.0
   968 	 * @access public
   971 	 * @access public
   969 	 * @var int
   972 	 * @var int
   970 	 */
   973 	 */
   971 	var $comment_count = 0;
   974 	public $comment_count = 0;
   972 
   975 
   973 	/**
   976 	/**
   974 	 * The index of the comment in the comment loop.
   977 	 * The index of the comment in the comment loop.
   975 	 *
   978 	 *
   976 	 * @since 2.2.0
   979 	 * @since 2.2.0
   977 	 * @access public
   980 	 * @access public
   978 	 * @var int
   981 	 * @var int
   979 	 */
   982 	 */
   980 	var $current_comment = -1;
   983 	public $current_comment = -1;
   981 
   984 
   982 	/**
   985 	/**
   983 	 * Current comment ID.
   986 	 * Current comment ID.
   984 	 *
   987 	 *
   985 	 * @since 2.2.0
   988 	 * @since 2.2.0
   986 	 * @access public
   989 	 * @access public
   987 	 * @var int
   990 	 * @var int
   988 	 */
   991 	 */
   989 	var $comment;
   992 	public $comment;
   990 
   993 
   991 	/**
   994 	/**
   992 	 * The amount of found posts for the current query.
   995 	 * The amount of found posts for the current query.
   993 	 *
   996 	 *
   994 	 * If limit clause was not used, equals $post_count.
   997 	 * If limit clause was not used, equals $post_count.
   995 	 *
   998 	 *
   996 	 * @since 2.1.0
   999 	 * @since 2.1.0
   997 	 * @access public
  1000 	 * @access public
   998 	 * @var int
  1001 	 * @var int
   999 	 */
  1002 	 */
  1000 	var $found_posts = 0;
  1003 	public $found_posts = 0;
  1001 
  1004 
  1002 	/**
  1005 	/**
  1003 	 * The amount of pages.
  1006 	 * The amount of pages.
  1004 	 *
  1007 	 *
  1005 	 * @since 2.1.0
  1008 	 * @since 2.1.0
  1006 	 * @access public
  1009 	 * @access public
  1007 	 * @var int
  1010 	 * @var int
  1008 	 */
  1011 	 */
  1009 	var $max_num_pages = 0;
  1012 	public $max_num_pages = 0;
  1010 
  1013 
  1011 	/**
  1014 	/**
  1012 	 * The amount of comment pages.
  1015 	 * The amount of comment pages.
  1013 	 *
  1016 	 *
  1014 	 * @since 2.7.0
  1017 	 * @since 2.7.0
  1015 	 * @access public
  1018 	 * @access public
  1016 	 * @var int
  1019 	 * @var int
  1017 	 */
  1020 	 */
  1018 	var $max_num_comment_pages = 0;
  1021 	public $max_num_comment_pages = 0;
  1019 
  1022 
  1020 	/**
  1023 	/**
  1021 	 * Set if query is single post.
  1024 	 * Set if query is single post.
  1022 	 *
  1025 	 *
  1023 	 * @since 1.5.0
  1026 	 * @since 1.5.0
  1024 	 * @access public
  1027 	 * @access public
  1025 	 * @var bool
  1028 	 * @var bool
  1026 	 */
  1029 	 */
  1027 	var $is_single = false;
  1030 	public $is_single = false;
  1028 
  1031 
  1029 	/**
  1032 	/**
  1030 	 * Set if query is preview of blog.
  1033 	 * Set if query is preview of blog.
  1031 	 *
  1034 	 *
  1032 	 * @since 2.0.0
  1035 	 * @since 2.0.0
  1033 	 * @access public
  1036 	 * @access public
  1034 	 * @var bool
  1037 	 * @var bool
  1035 	 */
  1038 	 */
  1036 	var $is_preview = false;
  1039 	public $is_preview = false;
  1037 
  1040 
  1038 	/**
  1041 	/**
  1039 	 * Set if query returns a page.
  1042 	 * Set if query returns a page.
  1040 	 *
  1043 	 *
  1041 	 * @since 1.5.0
  1044 	 * @since 1.5.0
  1042 	 * @access public
  1045 	 * @access public
  1043 	 * @var bool
  1046 	 * @var bool
  1044 	 */
  1047 	 */
  1045 	var $is_page = false;
  1048 	public $is_page = false;
  1046 
  1049 
  1047 	/**
  1050 	/**
  1048 	 * Set if query is an archive list.
  1051 	 * Set if query is an archive list.
  1049 	 *
  1052 	 *
  1050 	 * @since 1.5.0
  1053 	 * @since 1.5.0
  1051 	 * @access public
  1054 	 * @access public
  1052 	 * @var bool
  1055 	 * @var bool
  1053 	 */
  1056 	 */
  1054 	var $is_archive = false;
  1057 	public $is_archive = false;
  1055 
  1058 
  1056 	/**
  1059 	/**
  1057 	 * Set if query is part of a date.
  1060 	 * Set if query is part of a date.
  1058 	 *
  1061 	 *
  1059 	 * @since 1.5.0
  1062 	 * @since 1.5.0
  1060 	 * @access public
  1063 	 * @access public
  1061 	 * @var bool
  1064 	 * @var bool
  1062 	 */
  1065 	 */
  1063 	var $is_date = false;
  1066 	public $is_date = false;
  1064 
  1067 
  1065 	/**
  1068 	/**
  1066 	 * Set if query contains a year.
  1069 	 * Set if query contains a year.
  1067 	 *
  1070 	 *
  1068 	 * @since 1.5.0
  1071 	 * @since 1.5.0
  1069 	 * @access public
  1072 	 * @access public
  1070 	 * @var bool
  1073 	 * @var bool
  1071 	 */
  1074 	 */
  1072 	var $is_year = false;
  1075 	public $is_year = false;
  1073 
  1076 
  1074 	/**
  1077 	/**
  1075 	 * Set if query contains a month.
  1078 	 * Set if query contains a month.
  1076 	 *
  1079 	 *
  1077 	 * @since 1.5.0
  1080 	 * @since 1.5.0
  1078 	 * @access public
  1081 	 * @access public
  1079 	 * @var bool
  1082 	 * @var bool
  1080 	 */
  1083 	 */
  1081 	var $is_month = false;
  1084 	public $is_month = false;
  1082 
  1085 
  1083 	/**
  1086 	/**
  1084 	 * Set if query contains a day.
  1087 	 * Set if query contains a day.
  1085 	 *
  1088 	 *
  1086 	 * @since 1.5.0
  1089 	 * @since 1.5.0
  1087 	 * @access public
  1090 	 * @access public
  1088 	 * @var bool
  1091 	 * @var bool
  1089 	 */
  1092 	 */
  1090 	var $is_day = false;
  1093 	public $is_day = false;
  1091 
  1094 
  1092 	/**
  1095 	/**
  1093 	 * Set if query contains time.
  1096 	 * Set if query contains time.
  1094 	 *
  1097 	 *
  1095 	 * @since 1.5.0
  1098 	 * @since 1.5.0
  1096 	 * @access public
  1099 	 * @access public
  1097 	 * @var bool
  1100 	 * @var bool
  1098 	 */
  1101 	 */
  1099 	var $is_time = false;
  1102 	public $is_time = false;
  1100 
  1103 
  1101 	/**
  1104 	/**
  1102 	 * Set if query contains an author.
  1105 	 * Set if query contains an author.
  1103 	 *
  1106 	 *
  1104 	 * @since 1.5.0
  1107 	 * @since 1.5.0
  1105 	 * @access public
  1108 	 * @access public
  1106 	 * @var bool
  1109 	 * @var bool
  1107 	 */
  1110 	 */
  1108 	var $is_author = false;
  1111 	public $is_author = false;
  1109 
  1112 
  1110 	/**
  1113 	/**
  1111 	 * Set if query contains category.
  1114 	 * Set if query contains category.
  1112 	 *
  1115 	 *
  1113 	 * @since 1.5.0
  1116 	 * @since 1.5.0
  1114 	 * @access public
  1117 	 * @access public
  1115 	 * @var bool
  1118 	 * @var bool
  1116 	 */
  1119 	 */
  1117 	var $is_category = false;
  1120 	public $is_category = false;
  1118 
  1121 
  1119 	/**
  1122 	/**
  1120 	 * Set if query contains tag.
  1123 	 * Set if query contains tag.
  1121 	 *
  1124 	 *
  1122 	 * @since 2.3.0
  1125 	 * @since 2.3.0
  1123 	 * @access public
  1126 	 * @access public
  1124 	 * @var bool
  1127 	 * @var bool
  1125 	 */
  1128 	 */
  1126 	var $is_tag = false;
  1129 	public $is_tag = false;
  1127 
  1130 
  1128 	/**
  1131 	/**
  1129 	 * Set if query contains taxonomy.
  1132 	 * Set if query contains taxonomy.
  1130 	 *
  1133 	 *
  1131 	 * @since 2.5.0
  1134 	 * @since 2.5.0
  1132 	 * @access public
  1135 	 * @access public
  1133 	 * @var bool
  1136 	 * @var bool
  1134 	 */
  1137 	 */
  1135 	var $is_tax = false;
  1138 	public $is_tax = false;
  1136 
  1139 
  1137 	/**
  1140 	/**
  1138 	 * Set if query was part of a search result.
  1141 	 * Set if query was part of a search result.
  1139 	 *
  1142 	 *
  1140 	 * @since 1.5.0
  1143 	 * @since 1.5.0
  1141 	 * @access public
  1144 	 * @access public
  1142 	 * @var bool
  1145 	 * @var bool
  1143 	 */
  1146 	 */
  1144 	var $is_search = false;
  1147 	public $is_search = false;
  1145 
  1148 
  1146 	/**
  1149 	/**
  1147 	 * Set if query is feed display.
  1150 	 * Set if query is feed display.
  1148 	 *
  1151 	 *
  1149 	 * @since 1.5.0
  1152 	 * @since 1.5.0
  1150 	 * @access public
  1153 	 * @access public
  1151 	 * @var bool
  1154 	 * @var bool
  1152 	 */
  1155 	 */
  1153 	var $is_feed = false;
  1156 	public $is_feed = false;
  1154 
  1157 
  1155 	/**
  1158 	/**
  1156 	 * Set if query is comment feed display.
  1159 	 * Set if query is comment feed display.
  1157 	 *
  1160 	 *
  1158 	 * @since 2.2.0
  1161 	 * @since 2.2.0
  1159 	 * @access public
  1162 	 * @access public
  1160 	 * @var bool
  1163 	 * @var bool
  1161 	 */
  1164 	 */
  1162 	var $is_comment_feed = false;
  1165 	public $is_comment_feed = false;
  1163 
  1166 
  1164 	/**
  1167 	/**
  1165 	 * Set if query is trackback.
  1168 	 * Set if query is trackback.
  1166 	 *
  1169 	 *
  1167 	 * @since 1.5.0
  1170 	 * @since 1.5.0
  1168 	 * @access public
  1171 	 * @access public
  1169 	 * @var bool
  1172 	 * @var bool
  1170 	 */
  1173 	 */
  1171 	var $is_trackback = false;
  1174 	public $is_trackback = false;
  1172 
  1175 
  1173 	/**
  1176 	/**
  1174 	 * Set if query is blog homepage.
  1177 	 * Set if query is blog homepage.
  1175 	 *
  1178 	 *
  1176 	 * @since 1.5.0
  1179 	 * @since 1.5.0
  1177 	 * @access public
  1180 	 * @access public
  1178 	 * @var bool
  1181 	 * @var bool
  1179 	 */
  1182 	 */
  1180 	var $is_home = false;
  1183 	public $is_home = false;
  1181 
  1184 
  1182 	/**
  1185 	/**
  1183 	 * Set if query couldn't found anything.
  1186 	 * Set if query couldn't found anything.
  1184 	 *
  1187 	 *
  1185 	 * @since 1.5.0
  1188 	 * @since 1.5.0
  1186 	 * @access public
  1189 	 * @access public
  1187 	 * @var bool
  1190 	 * @var bool
  1188 	 */
  1191 	 */
  1189 	var $is_404 = false;
  1192 	public $is_404 = false;
  1190 
  1193 
  1191 	/**
  1194 	/**
  1192 	 * Set if query is within comments popup window.
  1195 	 * Set if query is within comments popup window.
  1193 	 *
  1196 	 *
  1194 	 * @since 1.5.0
  1197 	 * @since 1.5.0
  1195 	 * @access public
  1198 	 * @access public
  1196 	 * @var bool
  1199 	 * @var bool
  1197 	 */
  1200 	 */
  1198 	var $is_comments_popup = false;
  1201 	public $is_comments_popup = false;
  1199 
  1202 
  1200 	/**
  1203 	/**
  1201 	 * Set if query is paged
  1204 	 * Set if query is paged
  1202 	 *
  1205 	 *
  1203 	 * @since 1.5.0
  1206 	 * @since 1.5.0
  1204 	 * @access public
  1207 	 * @access public
  1205 	 * @var bool
  1208 	 * @var bool
  1206 	 */
  1209 	 */
  1207 	var $is_paged = false;
  1210 	public $is_paged = false;
  1208 
  1211 
  1209 	/**
  1212 	/**
  1210 	 * Set if query is part of administration page.
  1213 	 * Set if query is part of administration page.
  1211 	 *
  1214 	 *
  1212 	 * @since 1.5.0
  1215 	 * @since 1.5.0
  1213 	 * @access public
  1216 	 * @access public
  1214 	 * @var bool
  1217 	 * @var bool
  1215 	 */
  1218 	 */
  1216 	var $is_admin = false;
  1219 	public $is_admin = false;
  1217 
  1220 
  1218 	/**
  1221 	/**
  1219 	 * Set if query is an attachment.
  1222 	 * Set if query is an attachment.
  1220 	 *
  1223 	 *
  1221 	 * @since 2.0.0
  1224 	 * @since 2.0.0
  1222 	 * @access public
  1225 	 * @access public
  1223 	 * @var bool
  1226 	 * @var bool
  1224 	 */
  1227 	 */
  1225 	var $is_attachment = false;
  1228 	public $is_attachment = false;
  1226 
  1229 
  1227 	/**
  1230 	/**
  1228 	 * Set if is single, is a page, or is an attachment.
  1231 	 * Set if is single, is a page, or is an attachment.
  1229 	 *
  1232 	 *
  1230 	 * @since 2.1.0
  1233 	 * @since 2.1.0
  1231 	 * @access public
  1234 	 * @access public
  1232 	 * @var bool
  1235 	 * @var bool
  1233 	 */
  1236 	 */
  1234 	var $is_singular = false;
  1237 	public $is_singular = false;
  1235 
  1238 
  1236 	/**
  1239 	/**
  1237 	 * Set if query is for robots.
  1240 	 * Set if query is for robots.
  1238 	 *
  1241 	 *
  1239 	 * @since 2.1.0
  1242 	 * @since 2.1.0
  1240 	 * @access public
  1243 	 * @access public
  1241 	 * @var bool
  1244 	 * @var bool
  1242 	 */
  1245 	 */
  1243 	var $is_robots = false;
  1246 	public $is_robots = false;
  1244 
  1247 
  1245 	/**
  1248 	/**
  1246 	 * Set if query contains posts.
  1249 	 * Set if query contains posts.
  1247 	 *
  1250 	 *
  1248 	 * Basically, the homepage if the option isn't set for the static homepage.
  1251 	 * Basically, the homepage if the option isn't set for the static homepage.
  1249 	 *
  1252 	 *
  1250 	 * @since 2.1.0
  1253 	 * @since 2.1.0
  1251 	 * @access public
  1254 	 * @access public
  1252 	 * @var bool
  1255 	 * @var bool
  1253 	 */
  1256 	 */
  1254 	var $is_posts_page = false;
  1257 	public $is_posts_page = false;
  1255 
  1258 
  1256 	/**
  1259 	/**
  1257 	 * Set if query is for a post type archive.
  1260 	 * Set if query is for a post type archive.
  1258 	 *
  1261 	 *
  1259 	 * @since 3.1.0
  1262 	 * @since 3.1.0
  1260 	 * @access public
  1263 	 * @access public
  1261 	 * @var bool
  1264 	 * @var bool
  1262 	 */
  1265 	 */
  1263 	var $is_post_type_archive = false;
  1266 	public $is_post_type_archive = false;
  1264 
  1267 
  1265 	/**
  1268 	/**
  1266 	 * Stores the ->query_vars state like md5(serialize( $this->query_vars ) ) so we know
  1269 	 * Stores the ->query_vars state like md5(serialize( $this->query_vars ) ) so we know
  1267 	 * whether we have to re-parse because something has changed
  1270 	 * whether we have to re-parse because something has changed
  1268 	 *
  1271 	 *
  1269 	 * @since 3.1.0
  1272 	 * @since 3.1.0
  1270 	 * @access private
  1273 	 * @access private
  1271 	 */
  1274 	 * @var bool|string
  1272 	var $query_vars_hash = false;
  1275 	 */
       
  1276 	private $query_vars_hash = false;
  1273 
  1277 
  1274 	/**
  1278 	/**
  1275 	 * Whether query vars have changed since the initial parse_query() call. Used to catch modifications to query vars made
  1279 	 * Whether query vars have changed since the initial parse_query() call. Used to catch modifications to query vars made
  1276 	 * via pre_get_posts hooks.
  1280 	 * via pre_get_posts hooks.
  1277 	 *
  1281 	 *
  1278 	 * @since 3.1.1
  1282 	 * @since 3.1.1
  1279 	 * @access private
  1283 	 * @access private
  1280 	 */
  1284 	 */
  1281 	var $query_vars_changed = true;
  1285 	private $query_vars_changed = true;
  1282 
  1286 
  1283 	/**
  1287 	/**
  1284 	 * Set if post thumbnails are cached
  1288 	 * Set if post thumbnails are cached
  1285 	 *
  1289 	 *
  1286 	 * @since 3.2.0
  1290 	 * @since 3.2.0
  1287 	 * @access public
  1291 	 * @access public
  1288 	 * @var bool
  1292 	 * @var bool
  1289 	 */
  1293 	 */
  1290 	 var $thumbnails_cached = false;
  1294 	 public $thumbnails_cached = false;
  1291 
  1295 
  1292 	/**
  1296 	/**
  1293 	 * Cached list of search stopwords.
  1297 	 * Cached list of search stopwords.
  1294 	 *
  1298 	 *
  1295 	 * @since 3.7.0
  1299 	 * @since 3.7.0
  1296 	 * @var array
  1300 	 * @var array
  1297 	 */
  1301 	 */
  1298 	private $stopwords;
  1302 	private $stopwords;
  1299 
  1303 
       
  1304 	private $compat_fields = array( 'query_vars_hash', 'query_vars_changed' );
       
  1305 
       
  1306 	private $compat_methods = array( 'init_query_flags', 'parse_tax_query' );
       
  1307 
  1300 	/**
  1308 	/**
  1301 	 * Resets query flags to false.
  1309 	 * Resets query flags to false.
  1302 	 *
  1310 	 *
  1303 	 * The query flags are what page info WordPress was able to figure out.
  1311 	 * The query flags are what page info WordPress was able to figure out.
  1304 	 *
  1312 	 *
  1305 	 * @since 2.0.0
  1313 	 * @since 2.0.0
  1306 	 * @access private
  1314 	 * @access private
  1307 	 */
  1315 	 */
  1308 	function init_query_flags() {
  1316 	private function init_query_flags() {
  1309 		$this->is_single = false;
  1317 		$this->is_single = false;
  1310 		$this->is_preview = false;
  1318 		$this->is_preview = false;
  1311 		$this->is_page = false;
  1319 		$this->is_page = false;
  1312 		$this->is_archive = false;
  1320 		$this->is_archive = false;
  1313 		$this->is_date = false;
  1321 		$this->is_date = false;
  1339 	 * Initiates object properties and sets default values.
  1347 	 * Initiates object properties and sets default values.
  1340 	 *
  1348 	 *
  1341 	 * @since 1.5.0
  1349 	 * @since 1.5.0
  1342 	 * @access public
  1350 	 * @access public
  1343 	 */
  1351 	 */
  1344 	function init() {
  1352 	public function init() {
  1345 		unset($this->posts);
  1353 		unset($this->posts);
  1346 		unset($this->query);
  1354 		unset($this->query);
  1347 		$this->query_vars = array();
  1355 		$this->query_vars = array();
  1348 		unset($this->queried_object);
  1356 		unset($this->queried_object);
  1349 		unset($this->queried_object_id);
  1357 		unset($this->queried_object_id);
  1367 	 * Reparse the query vars.
  1375 	 * Reparse the query vars.
  1368 	 *
  1376 	 *
  1369 	 * @since 1.5.0
  1377 	 * @since 1.5.0
  1370 	 * @access public
  1378 	 * @access public
  1371 	 */
  1379 	 */
  1372 	function parse_query_vars() {
  1380 	public function parse_query_vars() {
  1373 		$this->parse_query();
  1381 		$this->parse_query();
  1374 	}
  1382 	}
  1375 
  1383 
  1376 	/**
  1384 	/**
  1377 	 * Fills in the query variables, which do not exist within the parameter.
  1385 	 * Fills in the query variables, which do not exist within the parameter.
  1380 	 * @access public
  1388 	 * @access public
  1381 	 *
  1389 	 *
  1382 	 * @param array $array Defined query variables.
  1390 	 * @param array $array Defined query variables.
  1383 	 * @return array Complete query variables with undefined ones filled in empty.
  1391 	 * @return array Complete query variables with undefined ones filled in empty.
  1384 	 */
  1392 	 */
  1385 	function fill_query_vars($array) {
  1393 	public function fill_query_vars($array) {
  1386 		$keys = array(
  1394 		$keys = array(
  1387 			'error'
  1395 			'error'
  1388 			, 'm'
  1396 			, 'm'
  1389 			, 'p'
  1397 			, 'p'
  1390 			, 'post_parent'
  1398 			, 'post_parent'
  1440 
  1448 
  1441 	/**
  1449 	/**
  1442 	 * Parse a query string and set query type booleans.
  1450 	 * Parse a query string and set query type booleans.
  1443 	 *
  1451 	 *
  1444 	 * @since 1.5.0
  1452 	 * @since 1.5.0
  1445 	 * @access public
  1453 	 * @since 4.2.0 Introduced the ability to order by specific clauses of a `$meta_query`, by passing the clause's
  1446 	 *
  1454 	 *              array key to `$orderby`.
  1447 	 * @param string|array $query Optional query.
  1455 	 * @access public
  1448 	 */
  1456 	 *
  1449 	function parse_query( $query =  '' ) {
  1457 	 * @param string|array $query {
       
  1458 	 *     Optional. Array or string of Query parameters.
       
  1459 	 *
       
  1460 	 *     @type int          $attachment_id           Attachment post ID. Used for 'attachment' post_type.
       
  1461 	 *     @type int|string   $author                  Author ID, or comma-separated list of IDs.
       
  1462 	 *     @type string       $author_name             User 'user_nicename'.
       
  1463 	 *     @type array        $author__in              An array of author IDs to query from.
       
  1464 	 *     @type array        $author__not_in          An array of author IDs not to query from.
       
  1465 	 *     @type bool         $cache_results           Whether to cache post information. Default true.
       
  1466 	 *     @type int|string   $cat                     Category ID or comma-separated list of IDs (this or any children).
       
  1467 	 *     @type array        $category__and           An array of category IDs (AND in).
       
  1468 	 *     @type array        $category__in            An array of category IDs (OR in, no children).
       
  1469 	 *     @type array        $category__not_in        An array of category IDs (NOT in).
       
  1470 	 *     @type string       $category_name           Use category slug (not name, this or any children).
       
  1471 	 *     @type int          $comments_per_page       The number of comments to return per page.
       
  1472 	 *                                                 Default 'comments_per_page' option.
       
  1473 	 *     @type int|string   $comments_popup          Whether the query is within the comments popup. Default empty.
       
  1474 	 *     @type array        $date_query              An associative array of WP_Date_Query arguments.
       
  1475 	 *                                                 {@see WP_Date_Query::__construct()}
       
  1476 	 *     @type int          $day                     Day of the month. Default empty. Accepts numbers 1-31.
       
  1477 	 *     @type bool         $exact                   Whether to search by exact keyword. Default false.
       
  1478 	 *     @type string|array $fields                  Which fields to return. Single field or all fields (string),
       
  1479 	 *                                                 or array of fields. 'id=>parent' uses 'id' and 'post_parent'.
       
  1480 	 *                                                 Default all fields. Accepts 'ids', 'id=>parent'.
       
  1481 	 *     @type int          $hour                    Hour of the day. Default empty. Accepts numbers 0-23.
       
  1482 	 *     @type int|bool     $ignore_sticky_posts     Whether to ignore sticky posts or not. Setting this to false
       
  1483 	 *                                                 excludes stickies from 'post__in'. Accepts 1|true, 0|false.
       
  1484 	 *                                                 Default 0|false.
       
  1485 	 *     @type int          $m                       Combination YearMonth. Accepts any four-digit year and month
       
  1486 	 *                                                 numbers 1-12. Default empty.
       
  1487 	 *     @type string       $meta_compare            Comparison operator to test the 'meta_value'.
       
  1488 	 *     @type string       $meta_key                Custom field key.
       
  1489 	 *     @type array        $meta_query              An associative array of WP_Meta_Query arguments.
       
  1490 	 *                                                 {@see WP_Meta_Query->queries}
       
  1491 	 *     @type string       $meta_value              Custom field value.
       
  1492 	 *     @type int          $meta_value_num          Custom field value number.
       
  1493 	 *     @type int          $menu_order              The menu order of the posts.
       
  1494 	 *     @type int          $monthnum                The two-digit month. Default empty. Accepts numbers 1-12.
       
  1495 	 *     @type string       $name                    Post slug.
       
  1496 	 *     @type bool         $nopaging                Show all posts (true) or paginate (false). Default false.
       
  1497 	 *     @type bool         $no_found_rows           Whether to skip counting the total rows found. Enabling can improve
       
  1498 	 *                                                 performance. Default false.
       
  1499 	 *     @type int          $offset                  The number of posts to offset before retrieval.
       
  1500 	 *     @type string       $order                   Designates ascending or descending order of posts. Default 'DESC'.
       
  1501 	 *                                                 Accepts 'ASC', 'DESC'.
       
  1502 	 *     @type string|array $orderby                 Sort retrieved posts by parameter. One or more options may be
       
  1503 	 *                                                 passed. To use 'meta_value', or 'meta_value_num',
       
  1504 	 *                                                 'meta_key=keyname' must be also be defined. To sort by a
       
  1505 	 *                                                 specific `$meta_query` clause, use that clause's array key.
       
  1506 	 *                                                 Default 'date'. Accepts 'none', 'name', 'author', 'date',
       
  1507 	 *                                                 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand',
       
  1508 	 *                                                 'comment_count', 'meta_value', 'meta_value_num', and the
       
  1509 	 *                                                 array keys of `$meta_query`.
       
  1510 	 *     @type int          $p                       Post ID.
       
  1511 	 *     @type int          $page                    Show the number of posts that would show up on page X of a
       
  1512 	 *                                                 static front page.
       
  1513 	 *     @type int          $paged                   The number of the current page.
       
  1514 	 *     @type int          $page_id                 Page ID.
       
  1515 	 *     @type string       $pagename                Page slug.
       
  1516 	 *     @type string       $perm                    Show posts if user has the appropriate capability.
       
  1517 	 *     @type array        $post__in                An array of post IDs to retrieve, sticky posts will be included
       
  1518 	 *     @type string       $post_mime_type          The mime type of the post. Used for 'attachment' post_type.
       
  1519 	 *     @type array        $post__not_in            An array of post IDs not to retrieve. Note: a string of comma-
       
  1520 	 *                                                 separated IDs will NOT work.
       
  1521 	 *     @type int          $post_parent             Page ID to retrieve child pages for. Use 0 to only retrieve
       
  1522 	 *                                                 top-level pages.
       
  1523 	 *     @type array        $post_parent__in         An array containing parent page IDs to query child pages from.
       
  1524 	 *     @type array        $post_parent__not_in     An array containing parent page IDs not to query child pages from.
       
  1525 	 *     @type string|array $post_type               A post type slug (string) or array of post type slugs.
       
  1526 	 *                                                 Default 'any' if using 'tax_query'.
       
  1527 	 *     @type string|array $post_status             A post status (string) or array of post statuses.
       
  1528 	 *     @type int          $posts_per_page          The number of posts to query for. Use -1 to request all posts.
       
  1529 	 *     @type int          $posts_per_archive_page  The number of posts to query for by archive page. Overrides
       
  1530 	 *                                                 'posts_per_page' when is_archive(), or is_search() are true.
       
  1531 	 *     @type string       $s                       Search keyword.
       
  1532 	 *     @type int          $second                  Second of the minute. Default empty. Accepts numbers 0-60.
       
  1533 	 *     @type array        $search_terms            Array of search terms.
       
  1534 	 *     @type bool         $sentence                Whether to search by phrase. Default false.
       
  1535 	 *     @type bool         $suppress_filters        Whether to suppress filters. Default false.
       
  1536 	 *     @type string       $tag                     Tag slug. Comma-separated (either), Plus-separated (all).
       
  1537 	 *     @type array        $tag__and                An array of tag ids (AND in).
       
  1538 	 *     @type array        $tag__in                 An array of tag ids (OR in).
       
  1539 	 *     @type array        $tag__not_in             An array of tag ids (NOT in).
       
  1540 	 *     @type int          $tag_id                  Tag id or comma-separated list of IDs.
       
  1541 	 *     @type array        $tag_slug__and           An array of tag slugs (AND in).
       
  1542 	 *     @type array        $tag_slug__in            An array of tag slugs (OR in). unless 'ignore_sticky_posts' is
       
  1543 	 *                                                 true. Note: a string of comma-separated IDs will NOT work.
       
  1544 	 *     @type array        $tax_query               An associative array of WP_Tax_Query arguments.
       
  1545 	 *                                                 {@see WP_Tax_Query->queries}
       
  1546 	 *     @type bool         $update_post_meta_cache  Whether to update the post meta cache. Default true.
       
  1547 	 *     @type bool         $update_post_term_cache  Whether to update the post term cache. Default true.
       
  1548 	 *     @type int          $w                       The week number of the year. Default empty. Accepts numbers 0-53.
       
  1549 	 *     @type int          $year                    The four-digit year. Default empty. Accepts any four-digit year.
       
  1550 	 * }
       
  1551 	 */
       
  1552 	public function parse_query( $query =  '' ) {
  1450 		if ( ! empty( $query ) ) {
  1553 		if ( ! empty( $query ) ) {
  1451 			$this->init();
  1554 			$this->init();
  1452 			$this->query = $this->query_vars = wp_parse_args( $query );
  1555 			$this->query = $this->query_vars = wp_parse_args( $query );
  1453 		} elseif ( ! isset( $this->query ) ) {
  1556 		} elseif ( ! isset( $this->query ) ) {
  1454 			$this->query = $this->query_vars;
  1557 			$this->query = $this->query_vars;
  1477 		if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']);
  1580 		if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']);
  1478 		if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']);
  1581 		if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']);
  1479 		if ( '' !== $qv['menu_order'] ) $qv['menu_order'] = absint($qv['menu_order']);
  1582 		if ( '' !== $qv['menu_order'] ) $qv['menu_order'] = absint($qv['menu_order']);
  1480 
  1583 
  1481 		// Fairly insane upper bound for search string lengths.
  1584 		// Fairly insane upper bound for search string lengths.
  1482 		if ( ! empty( $qv['s'] ) && strlen( $qv['s'] ) > 1600 )
  1585 		if ( ! is_scalar( $qv['s'] ) || ( ! empty( $qv['s'] ) && strlen( $qv['s'] ) > 1600 ) ) {
  1483 			$qv['s'] = '';
  1586 			$qv['s'] = '';
       
  1587 		}
  1484 
  1588 
  1485 		// Compat. Map subpost to attachment.
  1589 		// Compat. Map subpost to attachment.
  1486 		if ( '' != $qv['subpost'] )
  1590 		if ( '' != $qv['subpost'] )
  1487 			$qv['attachment'] = $qv['subpost'];
  1591 			$qv['attachment'] = $qv['subpost'];
  1488 		if ( '' != $qv['subpost_id'] )
  1592 		if ( '' != $qv['subpost_id'] )
  1503 			$this->is_single = true;
  1607 			$this->is_single = true;
  1504 		} elseif ( '' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id']) ) {
  1608 		} elseif ( '' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id']) ) {
  1505 			$this->is_page = true;
  1609 			$this->is_page = true;
  1506 			$this->is_single = false;
  1610 			$this->is_single = false;
  1507 		} else {
  1611 		} else {
  1508 		// Look for archive queries. Dates, categories, authors, search, post type archives.
  1612 			// Look for archive queries. Dates, categories, authors, search, post type archives.
  1509 
  1613 
  1510 			if ( !empty($qv['s']) ) {
  1614 			if ( isset( $this->query['s'] ) ) {
  1511 				$this->is_search = true;
  1615 				$this->is_search = true;
  1512 			}
  1616 			}
  1513 
  1617 
  1514 			if ( '' !== $qv['second'] ) {
  1618 			if ( '' !== $qv['second'] ) {
  1515 				$this->is_time = true;
  1619 				$this->is_time = true;
  1558 
  1662 
  1559 			if ( $qv['m'] ) {
  1663 			if ( $qv['m'] ) {
  1560 				$this->is_date = true;
  1664 				$this->is_date = true;
  1561 				if ( strlen($qv['m']) > 9 ) {
  1665 				if ( strlen($qv['m']) > 9 ) {
  1562 					$this->is_time = true;
  1666 					$this->is_time = true;
  1563 				} else if ( strlen($qv['m']) > 7 ) {
  1667 				} elseif ( strlen( $qv['m'] ) > 7 ) {
  1564 					$this->is_day = true;
  1668 					$this->is_day = true;
  1565 				} else if ( strlen($qv['m']) > 5 ) {
  1669 				} elseif ( strlen( $qv['m'] ) > 5 ) {
  1566 					$this->is_month = true;
  1670 					$this->is_month = true;
  1567 				} else {
  1671 				} else {
  1568 					$this->is_year = true;
  1672 					$this->is_year = true;
  1569 				}
  1673 				}
  1570 			}
  1674 			}
  1575 
  1679 
  1576 			$this->query_vars_hash = false;
  1680 			$this->query_vars_hash = false;
  1577 			$this->parse_tax_query( $qv );
  1681 			$this->parse_tax_query( $qv );
  1578 
  1682 
  1579 			foreach ( $this->tax_query->queries as $tax_query ) {
  1683 			foreach ( $this->tax_query->queries as $tax_query ) {
  1580 				if ( 'NOT IN' != $tax_query['operator'] ) {
  1684 				if ( ! is_array( $tax_query ) ) {
       
  1685 					continue;
       
  1686 				}
       
  1687 
       
  1688 				if ( isset( $tax_query['operator'] ) && 'NOT IN' != $tax_query['operator'] ) {
  1581 					switch ( $tax_query['taxonomy'] ) {
  1689 					switch ( $tax_query['taxonomy'] ) {
  1582 						case 'category':
  1690 						case 'category':
  1583 							$this->is_category = true;
  1691 							$this->is_category = true;
  1584 							break;
  1692 							break;
  1585 						case 'post_tag':
  1693 						case 'post_tag':
  1707 			$this->set_404();
  1815 			$this->set_404();
  1708 
  1816 
  1709 		$this->query_vars_hash = md5( serialize( $this->query_vars ) );
  1817 		$this->query_vars_hash = md5( serialize( $this->query_vars ) );
  1710 		$this->query_vars_changed = false;
  1818 		$this->query_vars_changed = false;
  1711 
  1819 
  1712 		do_action_ref_array('parse_query', array(&$this));
  1820 		/**
  1713 	}
  1821 		 * Fires after the main query vars have been parsed.
  1714 
  1822 		 *
  1715 	/*
  1823 		 * @since 1.5.0
       
  1824 		 *
       
  1825 		 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  1826 		 */
       
  1827 		do_action_ref_array( 'parse_query', array( &$this ) );
       
  1828 	}
       
  1829 
       
  1830 	/**
  1716 	 * Parses various taxonomy related query vars.
  1831 	 * Parses various taxonomy related query vars.
       
  1832 	 *
       
  1833 	 * For BC, this method is not marked as protected. See [28987].
  1717 	 *
  1834 	 *
  1718 	 * @access protected
  1835 	 * @access protected
  1719 	 * @since 3.1.0
  1836 	 * @since 3.1.0
  1720 	 *
  1837 	 *
  1721 	 * @param array &$q The query variables
  1838 	 * @param array &$q The query variables
  1722 	 */
  1839 	 */
  1723 	function parse_tax_query( &$q ) {
  1840 	public function parse_tax_query( &$q ) {
  1724 		if ( ! empty( $q['tax_query'] ) && is_array( $q['tax_query'] ) ) {
  1841 		if ( ! empty( $q['tax_query'] ) && is_array( $q['tax_query'] ) ) {
  1725 			$tax_query = $q['tax_query'];
  1842 			$tax_query = $q['tax_query'];
  1726 		} else {
  1843 		} else {
  1727 			$tax_query = array();
  1844 			$tax_query = array();
  1728 		}
  1845 		}
  1765 				}
  1882 				}
  1766 			}
  1883 			}
  1767 		}
  1884 		}
  1768 
  1885 
  1769 		// Category stuff
  1886 		// Category stuff
  1770 		if ( !empty($q['cat']) && '0' != $q['cat'] && !$this->is_singular && $this->query_vars_changed ) {
  1887 		if ( ! empty( $q['cat'] ) && ! $this->is_singular ) {
  1771 			$q['cat'] = ''.urldecode($q['cat']).'';
  1888 			$cat_in = $cat_not_in = array();
  1772 			$q['cat'] = addslashes_gpc($q['cat']);
  1889 
  1773 			$cat_array = preg_split('/[,\s]+/', $q['cat']);
  1890 			$cat_array = preg_split( '/[,\s]+/', urldecode( $q['cat'] ) );
  1774 			$q['cat'] = '';
  1891 			$cat_array = array_map( 'intval', $cat_array );
  1775 			$req_cats = array();
  1892 			$q['cat'] = implode( ',', $cat_array );
  1776 			foreach ( (array) $cat_array as $cat ) {
  1893 
  1777 				$cat = intval($cat);
  1894 			foreach ( $cat_array as $cat ) {
  1778 				$req_cats[] = $cat;
  1895 				if ( $cat > 0 )
  1779 				$in = ($cat > 0);
  1896 					$cat_in[] = $cat;
  1780 				$cat = abs($cat);
  1897 				elseif ( $cat < 0 )
  1781 				if ( $in ) {
  1898 					$cat_not_in[] = abs( $cat );
  1782 					$q['category__in'][] = $cat;
  1899 			}
  1783 					$q['category__in'] = array_merge( $q['category__in'], get_term_children($cat, 'category') );
  1900 
  1784 				} else {
  1901 			if ( ! empty( $cat_in ) ) {
  1785 					$q['category__not_in'][] = $cat;
  1902 				$tax_query[] = array(
  1786 					$q['category__not_in'] = array_merge( $q['category__not_in'], get_term_children($cat, 'category') );
  1903 					'taxonomy' => 'category',
  1787 				}
  1904 					'terms' => $cat_in,
  1788 			}
  1905 					'field' => 'term_id',
  1789 			$q['cat'] = implode(',', $req_cats);
  1906 					'include_children' => true
       
  1907 				);
       
  1908 			}
       
  1909 
       
  1910 			if ( ! empty( $cat_not_in ) ) {
       
  1911 				$tax_query[] = array(
       
  1912 					'taxonomy' => 'category',
       
  1913 					'terms' => $cat_not_in,
       
  1914 					'field' => 'term_id',
       
  1915 					'operator' => 'NOT IN',
       
  1916 					'include_children' => true
       
  1917 				);
       
  1918 			}
       
  1919 			unset( $cat_array, $cat_in, $cat_not_in );
  1790 		}
  1920 		}
  1791 
  1921 
  1792 		if ( ! empty( $q['category__and'] ) && 1 === count( (array) $q['category__and'] ) ) {
  1922 		if ( ! empty( $q['category__and'] ) && 1 === count( (array) $q['category__and'] ) ) {
  1793 			$q['category__and'] = (array) $q['category__and'];
  1923 			$q['category__and'] = (array) $q['category__and'];
  1794 			if ( ! isset( $q['category__in'] ) )
  1924 			if ( ! isset( $q['category__in'] ) )
  1834 				$tags = preg_split('/[,\r\n\t ]+/', $q['tag']);
  1964 				$tags = preg_split('/[,\r\n\t ]+/', $q['tag']);
  1835 				foreach ( (array) $tags as $tag ) {
  1965 				foreach ( (array) $tags as $tag ) {
  1836 					$tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
  1966 					$tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
  1837 					$q['tag_slug__in'][] = $tag;
  1967 					$q['tag_slug__in'][] = $tag;
  1838 				}
  1968 				}
  1839 			} else if ( preg_match('/[+\r\n\t ]+/', $q['tag']) || !empty($q['cat']) ) {
  1969 			} elseif ( preg_match('/[+\r\n\t ]+/', $q['tag'] ) || ! empty( $q['cat'] ) ) {
  1840 				$tags = preg_split('/[+\r\n\t ]+/', $q['tag']);
  1970 				$tags = preg_split('/[+\r\n\t ]+/', $q['tag']);
  1841 				foreach ( (array) $tags as $tag ) {
  1971 				foreach ( (array) $tags as $tag ) {
  1842 					$tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
  1972 					$tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
  1843 					$q['tag_slug__and'][] = $tag;
  1973 					$q['tag_slug__and'][] = $tag;
  1844 				}
  1974 				}
  1901 			);
  2031 			);
  1902 		}
  2032 		}
  1903 
  2033 
  1904 		$this->tax_query = new WP_Tax_Query( $tax_query );
  2034 		$this->tax_query = new WP_Tax_Query( $tax_query );
  1905 
  2035 
       
  2036 		/**
       
  2037 		 * Fires after taxonomy-related query vars have been parsed.
       
  2038 		 *
       
  2039 		 * @since 3.7.0
       
  2040 		 *
       
  2041 		 * @param WP_Query $this The WP_Query instance.
       
  2042 		 */
  1906 		do_action( 'parse_tax_query', $this );
  2043 		do_action( 'parse_tax_query', $this );
  1907 	}
  2044 	}
  1908 
  2045 
  1909 	/**
  2046 	/**
  1910 	 * Generate SQL for the WHERE clause based on passed search terms.
  2047 	 * Generate SQL for the WHERE clause based on passed search terms.
  1911 	 *
  2048 	 *
  1912 	 * @since 3.7.0
  2049 	 * @since 3.7.0
  1913 	 *
  2050 	 *
  1914 	 * @global type $wpdb
  2051 	 * @global wpdb $wpdb
  1915 	 * @param array $q Query variables.
  2052 	 * @param array $q Query variables.
       
  2053 	 * @return string WHERE clause.
  1916 	 */
  2054 	 */
  1917 	protected function parse_search( &$q ) {
  2055 	protected function parse_search( &$q ) {
  1918 		global $wpdb;
  2056 		global $wpdb;
  1919 
  2057 
  1920 		$search = '';
  2058 		$search = '';
  1942 
  2080 
  1943 		$n = ! empty( $q['exact'] ) ? '' : '%';
  2081 		$n = ! empty( $q['exact'] ) ? '' : '%';
  1944 		$searchand = '';
  2082 		$searchand = '';
  1945 		$q['search_orderby_title'] = array();
  2083 		$q['search_orderby_title'] = array();
  1946 		foreach ( $q['search_terms'] as $term ) {
  2084 		foreach ( $q['search_terms'] as $term ) {
  1947 			$term = like_escape( esc_sql( $term ) );
  2085 			if ( $n ) {
  1948 			if ( $n )
  2086 				$like = '%' . $wpdb->esc_like( $term ) . '%';
  1949 				$q['search_orderby_title'][] = "$wpdb->posts.post_title LIKE '%$term%'";
  2087 				$q['search_orderby_title'][] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $like );
  1950 
  2088 			}
  1951 			$search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))";
  2089 
       
  2090 			$like = $n . $wpdb->esc_like( $term ) . $n;
       
  2091 			$search .= $wpdb->prepare( "{$searchand}(($wpdb->posts.post_title LIKE %s) OR ($wpdb->posts.post_content LIKE %s))", $like, $like );
  1952 			$searchand = ' AND ';
  2092 			$searchand = ' AND ';
  1953 		}
  2093 		}
  1954 
  2094 
  1955 		if ( ! empty( $search ) ) {
  2095 		if ( ! empty( $search ) ) {
  1956 			$search = " AND ({$search}) ";
  2096 			$search = " AND ({$search}) ";
  1968 	 * term matching when searching for posts. The list of English stopwords is
  2108 	 * term matching when searching for posts. The list of English stopwords is
  1969 	 * the approximate search engines list, and is translatable.
  2109 	 * the approximate search engines list, and is translatable.
  1970 	 *
  2110 	 *
  1971 	 * @since 3.7.0
  2111 	 * @since 3.7.0
  1972 	 *
  2112 	 *
  1973 	 * @param array Terms to check.
  2113 	 * @param array $terms Terms to check.
  1974 	 * @return array Terms that are not stopwords.
  2114 	 * @return array Terms that are not stopwords.
  1975 	 */
  2115 	 */
  1976 	protected function parse_search_terms( $terms ) {
  2116 	protected function parse_search_terms( $terms ) {
  1977 		$strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower';
  2117 		$strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower';
  1978 		$checked = array();
  2118 		$checked = array();
  2015 		 * words into your language. Instead, look for and provide commonly accepted stopwords in your language.
  2155 		 * words into your language. Instead, look for and provide commonly accepted stopwords in your language.
  2016 		 */
  2156 		 */
  2017 		$words = explode( ',', _x( 'about,an,are,as,at,be,by,com,for,from,how,in,is,it,of,on,or,that,the,this,to,was,what,when,where,who,will,with,www',
  2157 		$words = explode( ',', _x( 'about,an,are,as,at,be,by,com,for,from,how,in,is,it,of,on,or,that,the,this,to,was,what,when,where,who,will,with,www',
  2018 			'Comma-separated list of search stopwords in your language' ) );
  2158 			'Comma-separated list of search stopwords in your language' ) );
  2019 
  2159 
       
  2160 		$stopwords = array();
  2020 		foreach( $words as $word ) {
  2161 		foreach( $words as $word ) {
  2021 			$word = trim( $word, "\r\n\t " );
  2162 			$word = trim( $word, "\r\n\t " );
  2022 			if ( $word )
  2163 			if ( $word )
  2023 				$stopwords[] = $word;
  2164 				$stopwords[] = $word;
  2024 		}
  2165 		}
  2042 	 * @return string ORDER BY clause.
  2183 	 * @return string ORDER BY clause.
  2043 	 */
  2184 	 */
  2044 	protected function parse_search_order( &$q ) {
  2185 	protected function parse_search_order( &$q ) {
  2045 		global $wpdb;
  2186 		global $wpdb;
  2046 
  2187 
  2047 		$search_orderby = '';
       
  2048 
       
  2049 		if ( $q['search_terms_count'] > 1 ) {
  2188 		if ( $q['search_terms_count'] > 1 ) {
  2050 			$num_terms = count( $q['search_orderby_title'] );
  2189 			$num_terms = count( $q['search_orderby_title'] );
  2051 			$search_orderby_s = like_escape( esc_sql( $q['s'] ) );
  2190 			$like = '%' . $wpdb->esc_like( $q['s'] ) . '%';
  2052 
  2191 
  2053 			$search_orderby = '(CASE ';
  2192 			$search_orderby = '(CASE ';
  2054 			// sentence match in 'post_title'
  2193 			// sentence match in 'post_title'
  2055 			$search_orderby .= "WHEN $wpdb->posts.post_title LIKE '%{$search_orderby_s}%' THEN 1 ";
  2194 			$search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_title LIKE %s THEN 1 ", $like );
  2056 
  2195 
  2057 			// sanity limit, sort as sentence when more than 6 terms
  2196 			// sanity limit, sort as sentence when more than 6 terms
  2058 			// (few searches are longer than 6 terms and most titles are not)
  2197 			// (few searches are longer than 6 terms and most titles are not)
  2059 			if ( $num_terms < 7 ) {
  2198 			if ( $num_terms < 7 ) {
  2060 				// all words in title
  2199 				// all words in title
  2063 				if ( $num_terms > 1 )
  2202 				if ( $num_terms > 1 )
  2064 					$search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 3 ';
  2203 					$search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 3 ';
  2065 			}
  2204 			}
  2066 
  2205 
  2067 			// sentence match in 'post_content'
  2206 			// sentence match in 'post_content'
  2068 			$search_orderby .= "WHEN $wpdb->posts.post_content LIKE '%{$search_orderby_s}%' THEN 4 ";
  2207 			$search_orderby .= $wpdb->prepare( "WHEN $wpdb->posts.post_content LIKE %s THEN 4 ", $like );
  2069 			$search_orderby .= 'ELSE 5 END)';
  2208 			$search_orderby .= 'ELSE 5 END)';
  2070 		} else {
  2209 		} else {
  2071 			// single word or sentence search
  2210 			// single word or sentence search
  2072 			$search_orderby = reset( $q['search_orderby_title'] ) . ' DESC';
  2211 			$search_orderby = reset( $q['search_orderby_title'] ) . ' DESC';
  2073 		}
  2212 		}
  2074 
  2213 
  2075 		return $search_orderby;
  2214 		return $search_orderby;
  2076 	}
  2215 	}
  2077 
  2216 
  2078 	/**
  2217 	/**
       
  2218 	 * If the passed orderby value is allowed, convert the alias to a
       
  2219 	 * properly-prefixed orderby value.
       
  2220 	 *
       
  2221 	 * @since 4.0.0
       
  2222 	 * @access protected
       
  2223 	 *
       
  2224 	 * @global wpdb $wpdb WordPress database abstraction object.
       
  2225 	 *
       
  2226 	 * @param string $orderby Alias for the field to order by.
       
  2227 	 * @return string|bool Table-prefixed value to used in the ORDER clause. False otherwise.
       
  2228 	 */
       
  2229 	protected function parse_orderby( $orderby ) {
       
  2230 		global $wpdb;
       
  2231 
       
  2232 		// Used to filter values.
       
  2233 		$allowed_keys = array(
       
  2234 			'post_name', 'post_author', 'post_date', 'post_title', 'post_modified',
       
  2235 			'post_parent', 'post_type', 'name', 'author', 'date', 'title', 'modified',
       
  2236 			'parent', 'type', 'ID', 'menu_order', 'comment_count', 'rand',
       
  2237 		);
       
  2238 
       
  2239 		$primary_meta_key = '';
       
  2240 		$primary_meta_query = false;
       
  2241 		$meta_clauses = $this->meta_query->get_clauses();
       
  2242 		if ( ! empty( $meta_clauses ) ) {
       
  2243 			$primary_meta_query = reset( $meta_clauses );
       
  2244 
       
  2245 			if ( ! empty( $primary_meta_query['key'] ) ) {
       
  2246 				$primary_meta_key = $primary_meta_query['key'];
       
  2247 				$allowed_keys[] = $primary_meta_key;
       
  2248 			}
       
  2249 
       
  2250 			$allowed_keys[] = 'meta_value';
       
  2251 			$allowed_keys[] = 'meta_value_num';
       
  2252 			$allowed_keys   = array_merge( $allowed_keys, array_keys( $meta_clauses ) );
       
  2253 		}
       
  2254 
       
  2255 		if ( ! in_array( $orderby, $allowed_keys ) ) {
       
  2256 			return false;
       
  2257 		}
       
  2258 
       
  2259 		switch ( $orderby ) {
       
  2260 			case 'post_name':
       
  2261 			case 'post_author':
       
  2262 			case 'post_date':
       
  2263 			case 'post_title':
       
  2264 			case 'post_modified':
       
  2265 			case 'post_parent':
       
  2266 			case 'post_type':
       
  2267 			case 'ID':
       
  2268 			case 'menu_order':
       
  2269 			case 'comment_count':
       
  2270 				$orderby_clause = "$wpdb->posts.{$orderby}";
       
  2271 				break;
       
  2272 			case 'rand':
       
  2273 				$orderby_clause = 'RAND()';
       
  2274 				break;
       
  2275 			case $primary_meta_key:
       
  2276 			case 'meta_value':
       
  2277 				if ( ! empty( $primary_meta_query['type'] ) ) {
       
  2278 					$orderby_clause = "CAST({$primary_meta_query['alias']}.meta_value AS {$primary_meta_query['cast']})";
       
  2279 				} else {
       
  2280 					$orderby_clause = "{$primary_meta_query['alias']}.meta_value";
       
  2281 				}
       
  2282 				break;
       
  2283 			case 'meta_value_num':
       
  2284 				$orderby_clause = "{$primary_meta_query['alias']}.meta_value+0";
       
  2285 				break;
       
  2286 			default:
       
  2287 				if ( array_key_exists( $orderby, $meta_clauses ) ) {
       
  2288 					// $orderby corresponds to a meta_query clause.
       
  2289 					$meta_clause = $meta_clauses[ $orderby ];
       
  2290 					$orderby_clause = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})";
       
  2291 				} else {
       
  2292 					// Default: order by post field.
       
  2293 					$orderby_clause = "$wpdb->posts.post_" . sanitize_key( $orderby );
       
  2294 				}
       
  2295 
       
  2296 				break;
       
  2297 		}
       
  2298 
       
  2299 		return $orderby_clause;
       
  2300 	}
       
  2301 
       
  2302 	/**
       
  2303 	 * Parse an 'order' query variable and cast it to ASC or DESC as necessary.
       
  2304 	 *
       
  2305 	 * @since 4.0.0
       
  2306 	 * @access protected
       
  2307 	 *
       
  2308 	 * @param string $order The 'order' query variable.
       
  2309 	 * @return string The sanitized 'order' query variable.
       
  2310 	 */
       
  2311 	protected function parse_order( $order ) {
       
  2312 		if ( ! is_string( $order ) || empty( $order ) ) {
       
  2313 			return 'DESC';
       
  2314 		}
       
  2315 
       
  2316 		if ( 'ASC' === strtoupper( $order ) ) {
       
  2317 			return 'ASC';
       
  2318 		} else {
       
  2319 			return 'DESC';
       
  2320 		}
       
  2321 	}
       
  2322 
       
  2323 	/**
  2079 	 * Sets the 404 property and saves whether query is feed.
  2324 	 * Sets the 404 property and saves whether query is feed.
  2080 	 *
  2325 	 *
  2081 	 * @since 2.0.0
  2326 	 * @since 2.0.0
  2082 	 * @access public
  2327 	 * @access public
  2083 	 */
  2328 	 */
  2084 	function set_404() {
  2329 	public function set_404() {
  2085 		$is_feed = $this->is_feed;
  2330 		$is_feed = $this->is_feed;
  2086 
  2331 
  2087 		$this->init_query_flags();
  2332 		$this->init_query_flags();
  2088 		$this->is_404 = true;
  2333 		$this->is_404 = true;
  2089 
  2334 
  2095 	 *
  2340 	 *
  2096 	 * @since 1.5.0
  2341 	 * @since 1.5.0
  2097 	 * @access public
  2342 	 * @access public
  2098 	 *
  2343 	 *
  2099 	 * @param string $query_var Query variable key.
  2344 	 * @param string $query_var Query variable key.
       
  2345 	 * @param mixed  $default   Value to return if the query variable is not set. Default ''.
  2100 	 * @return mixed
  2346 	 * @return mixed
  2101 	 */
  2347 	 */
  2102 	function get($query_var) {
  2348 	public function get( $query_var, $default = '' ) {
  2103 		if ( isset($this->query_vars[$query_var]) )
  2349 		if ( isset( $this->query_vars[ $query_var ] ) ) {
  2104 			return $this->query_vars[$query_var];
  2350 			return $this->query_vars[ $query_var ];
  2105 
  2351 		}
  2106 		return '';
  2352 
       
  2353 		return $default;
  2107 	}
  2354 	}
  2108 
  2355 
  2109 	/**
  2356 	/**
  2110 	 * Set query variable.
  2357 	 * Set query variable.
  2111 	 *
  2358 	 *
  2113 	 * @access public
  2360 	 * @access public
  2114 	 *
  2361 	 *
  2115 	 * @param string $query_var Query variable key.
  2362 	 * @param string $query_var Query variable key.
  2116 	 * @param mixed $value Query variable value.
  2363 	 * @param mixed $value Query variable value.
  2117 	 */
  2364 	 */
  2118 	function set($query_var, $value) {
  2365 	public function set($query_var, $value) {
  2119 		$this->query_vars[$query_var] = $value;
  2366 		$this->query_vars[$query_var] = $value;
  2120 	}
  2367 	}
  2121 
  2368 
  2122 	/**
  2369 	/**
  2123 	 * Retrieve the posts based on query variables.
  2370 	 * Retrieve the posts based on query variables.
  2125 	 * There are a few filters and actions that can be used to modify the post
  2372 	 * There are a few filters and actions that can be used to modify the post
  2126 	 * database query.
  2373 	 * database query.
  2127 	 *
  2374 	 *
  2128 	 * @since 1.5.0
  2375 	 * @since 1.5.0
  2129 	 * @access public
  2376 	 * @access public
  2130 	 * @uses do_action_ref_array() Calls 'pre_get_posts' hook before retrieving posts.
       
  2131 	 *
  2377 	 *
  2132 	 * @return array List of posts.
  2378 	 * @return array List of posts.
  2133 	 */
  2379 	 */
  2134 	function get_posts() {
  2380 	public function get_posts() {
  2135 		global $wpdb;
  2381 		global $wpdb;
  2136 
  2382 
  2137 		$this->parse_query();
  2383 		$this->parse_query();
  2138 
  2384 
  2139 		do_action_ref_array('pre_get_posts', array(&$this));
  2385 		/**
       
  2386 		 * Fires after the query variable object is created, but before the actual query is run.
       
  2387 		 *
       
  2388 		 * Note: If using conditional tags, use the method versions within the passed instance
       
  2389 		 * (e.g. $this->is_main_query() instead of is_main_query()). This is because the functions
       
  2390 		 * like is_main_query() test against the global $wp_query instance, not the passed one.
       
  2391 		 *
       
  2392 		 * @since 2.0.0
       
  2393 		 *
       
  2394 		 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  2395 		 */
       
  2396 		do_action_ref_array( 'pre_get_posts', array( &$this ) );
  2140 
  2397 
  2141 		// Shorthand.
  2398 		// Shorthand.
  2142 		$q = &$this->query_vars;
  2399 		$q = &$this->query_vars;
  2143 
  2400 
  2144 		// Fill again in case pre_get_posts unset some vars.
  2401 		// Fill again in case pre_get_posts unset some vars.
  2163 		$where = '';
  2420 		$where = '';
  2164 		$limits = '';
  2421 		$limits = '';
  2165 		$join = '';
  2422 		$join = '';
  2166 		$search = '';
  2423 		$search = '';
  2167 		$groupby = '';
  2424 		$groupby = '';
  2168 		$fields = '';
       
  2169 		$post_status_join = false;
  2425 		$post_status_join = false;
  2170 		$page = 1;
  2426 		$page = 1;
  2171 
  2427 
  2172 		if ( isset( $q['caller_get_posts'] ) ) {
  2428 		if ( isset( $q['caller_get_posts'] ) ) {
  2173 			_deprecated_argument( 'WP_Query', '3.1', __( '"caller_get_posts" is deprecated. Use "ignore_sticky_posts" instead.' ) );
  2429 			_deprecated_argument( 'WP_Query', '3.1', __( '"caller_get_posts" is deprecated. Use "ignore_sticky_posts" instead.' ) );
  2199 				$q['post_type'] = 'any';
  2455 				$q['post_type'] = 'any';
  2200 			else
  2456 			else
  2201 				$q['post_type'] = '';
  2457 				$q['post_type'] = '';
  2202 		}
  2458 		}
  2203 		$post_type = $q['post_type'];
  2459 		$post_type = $q['post_type'];
  2204 		if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 )
  2460 		if ( empty( $q['posts_per_page'] ) ) {
  2205 			$q['posts_per_page'] = get_option('posts_per_page');
  2461 			$q['posts_per_page'] = get_option( 'posts_per_page' );
       
  2462 		}
  2206 		if ( isset($q['showposts']) && $q['showposts'] ) {
  2463 		if ( isset($q['showposts']) && $q['showposts'] ) {
  2207 			$q['showposts'] = (int) $q['showposts'];
  2464 			$q['showposts'] = (int) $q['showposts'];
  2208 			$q['posts_per_page'] = $q['showposts'];
  2465 			$q['posts_per_page'] = $q['showposts'];
  2209 		}
  2466 		}
  2210 		if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) )
  2467 		if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) )
  2214 				$q['nopaging'] = true;
  2471 				$q['nopaging'] = true;
  2215 			} else {
  2472 			} else {
  2216 				$q['nopaging'] = false;
  2473 				$q['nopaging'] = false;
  2217 			}
  2474 			}
  2218 		}
  2475 		}
       
  2476 
  2219 		if ( $this->is_feed ) {
  2477 		if ( $this->is_feed ) {
  2220 			$q['posts_per_page'] = get_option('posts_per_rss');
  2478 			// This overrides posts_per_page.
       
  2479 			if ( ! empty( $q['posts_per_rss'] ) ) {
       
  2480 				$q['posts_per_page'] = $q['posts_per_rss'];
       
  2481 			} else {
       
  2482 				$q['posts_per_page'] = get_option( 'posts_per_rss' );
       
  2483 			}
  2221 			$q['nopaging'] = false;
  2484 			$q['nopaging'] = false;
  2222 		}
  2485 		}
  2223 		$q['posts_per_page'] = (int) $q['posts_per_page'];
  2486 		$q['posts_per_page'] = (int) $q['posts_per_page'];
  2224 		if ( $q['posts_per_page'] < -1 )
  2487 		if ( $q['posts_per_page'] < -1 )
  2225 			$q['posts_per_page'] = abs($q['posts_per_page']);
  2488 			$q['posts_per_page'] = abs($q['posts_per_page']);
  2226 		else if ( $q['posts_per_page'] == 0 )
  2489 		elseif ( $q['posts_per_page'] == 0 )
  2227 			$q['posts_per_page'] = 1;
  2490 			$q['posts_per_page'] = 1;
  2228 
  2491 
  2229 		if ( !isset($q['comments_per_page']) || $q['comments_per_page'] == 0 )
  2492 		if ( !isset($q['comments_per_page']) || $q['comments_per_page'] == 0 )
  2230 			$q['comments_per_page'] = get_option('comments_per_page');
  2493 			$q['comments_per_page'] = get_option('comments_per_page');
  2231 
  2494 
  2317 			foreach ( (array)$q['post_type'] as $_post_type ) {
  2580 			foreach ( (array)$q['post_type'] as $_post_type ) {
  2318 				$ptype_obj = get_post_type_object($_post_type);
  2581 				$ptype_obj = get_post_type_object($_post_type);
  2319 				if ( !$ptype_obj || !$ptype_obj->query_var || empty($q[ $ptype_obj->query_var ]) )
  2582 				if ( !$ptype_obj || !$ptype_obj->query_var || empty($q[ $ptype_obj->query_var ]) )
  2320 					continue;
  2583 					continue;
  2321 
  2584 
  2322 				if ( ! $ptype_obj->hierarchical || strpos($q[ $ptype_obj->query_var ], '/') === false ) {
  2585 				if ( ! $ptype_obj->hierarchical ) {
  2323 					// Non-hierarchical post_types & parent-level-hierarchical post_types can directly use 'name'
  2586 					// Non-hierarchical post types can directly use 'name'.
  2324 					$q['name'] = $q[ $ptype_obj->query_var ];
  2587 					$q['name'] = $q[ $ptype_obj->query_var ];
  2325 				} else {
  2588 				} else {
  2326 					// Hierarchical post_types will operate through the
  2589 					// Hierarchical post types will operate through 'pagename'.
  2327 					$q['pagename'] = $q[ $ptype_obj->query_var ];
  2590 					$q['pagename'] = $q[ $ptype_obj->query_var ];
  2328 					$q['name'] = '';
  2591 					$q['name'] = '';
  2329 				}
  2592 				}
  2330 
  2593 
  2331 				// Only one request for a slug is possible, this is why name & pagename are overwritten above.
  2594 				// Only one request for a slug is possible, this is why name & pagename are overwritten above.
  2415 				$where = " AND {$wpdb->posts}.ID = " . $q['page_id'];
  2678 				$where = " AND {$wpdb->posts}.ID = " . $q['page_id'];
  2416 			}
  2679 			}
  2417 		}
  2680 		}
  2418 
  2681 
  2419 		// If a search pattern is specified, load the posts that match.
  2682 		// If a search pattern is specified, load the posts that match.
  2420 		if ( ! empty( $q['s'] ) )
  2683 		if ( ! empty( $q['s'] ) ) {
  2421 			$search = $this->parse_search( $q );
  2684 			$search = $this->parse_search( $q );
       
  2685 		}
  2422 
  2686 
  2423 		/**
  2687 		/**
  2424 		 * Filter the search SQL that is used in the WHERE clause of WP_Query.
  2688 		 * Filter the search SQL that is used in the WHERE clause of WP_Query.
  2425 		 *
  2689 		 *
  2426 		 * @since 3.0.0
  2690 		 * @since 3.0.0
  2442 
  2706 
  2443 		if ( $this->is_tax ) {
  2707 		if ( $this->is_tax ) {
  2444 			if ( empty($post_type) ) {
  2708 			if ( empty($post_type) ) {
  2445 				// Do a fully inclusive search for currently registered post types of queried taxonomies
  2709 				// Do a fully inclusive search for currently registered post types of queried taxonomies
  2446 				$post_type = array();
  2710 				$post_type = array();
  2447 				$taxonomies = wp_list_pluck( $this->tax_query->queries, 'taxonomy' );
  2711 				$taxonomies = array_keys( $this->tax_query->queried_terms );
  2448 				foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) {
  2712 				foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) {
  2449 					$object_taxonomies = $pt === 'attachment' ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt );
  2713 					$object_taxonomies = $pt === 'attachment' ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt );
  2450 					if ( array_intersect( $taxonomies, $object_taxonomies ) )
  2714 					if ( array_intersect( $taxonomies, $object_taxonomies ) )
  2451 						$post_type[] = $pt;
  2715 						$post_type[] = $pt;
  2452 				}
  2716 				}
  2459 			} elseif ( in_array('attachment', (array) $post_type) ) {
  2723 			} elseif ( in_array('attachment', (array) $post_type) ) {
  2460 				$post_status_join = true;
  2724 				$post_status_join = true;
  2461 			}
  2725 			}
  2462 		}
  2726 		}
  2463 
  2727 
  2464 		// Back-compat
  2728 		/*
  2465 		if ( !empty($this->tax_query->queries) ) {
  2729 		 * Ensure that 'taxonomy', 'term', 'term_id', 'cat', and
  2466 			$tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' );
  2730 		 * 'category_name' vars are set for backward compatibility.
  2467 			if ( !empty( $tax_query_in_and ) ) {
  2731 		 */
  2468 				if ( !isset( $q['taxonomy'] ) ) {
  2732 		if ( ! empty( $this->tax_query->queried_terms ) ) {
  2469 					foreach ( $tax_query_in_and as $a_tax_query ) {
  2733 
  2470 						if ( !in_array( $a_tax_query['taxonomy'], array( 'category', 'post_tag' ) ) ) {
  2734 			/*
  2471 							$q['taxonomy'] = $a_tax_query['taxonomy'];
  2735 			 * Set 'taxonomy', 'term', and 'term_id' to the
  2472 							if ( 'slug' == $a_tax_query['field'] )
  2736 			 * first taxonomy other than 'post_tag' or 'category'.
  2473 								$q['term'] = $a_tax_query['terms'][0];
  2737 			 */
  2474 							else
  2738 			if ( ! isset( $q['taxonomy'] ) ) {
  2475 								$q['term_id'] = $a_tax_query['terms'][0];
  2739 				foreach ( $this->tax_query->queried_terms as $queried_taxonomy => $queried_items ) {
  2476 
  2740 					if ( empty( $queried_items['terms'][0] ) ) {
  2477 							break;
  2741 						continue;
       
  2742 					}
       
  2743 
       
  2744 					if ( ! in_array( $queried_taxonomy, array( 'category', 'post_tag' ) ) ) {
       
  2745 						$q['taxonomy'] = $queried_taxonomy;
       
  2746 
       
  2747 						if ( 'slug' === $queried_items['field'] ) {
       
  2748 							$q['term'] = $queried_items['terms'][0];
       
  2749 						} else {
       
  2750 							$q['term_id'] = $queried_items['terms'][0];
  2478 						}
  2751 						}
  2479 					}
  2752 					}
  2480 				}
  2753 				}
  2481 
  2754 			}
  2482 				$cat_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'category' ) );
  2755 
  2483 				if ( ! empty( $cat_query ) ) {
  2756 			// 'cat', 'category_name', 'tag_id'
  2484 					$cat_query = reset( $cat_query );
  2757 			foreach ( $this->tax_query->queried_terms as $queried_taxonomy => $queried_items ) {
  2485 
  2758 				if ( empty( $queried_items['terms'][0] ) ) {
  2486 					if ( ! empty( $cat_query['terms'][0] ) ) {
  2759 					continue;
  2487 						$the_cat = get_term_by( $cat_query['field'], $cat_query['terms'][0], 'category' );
  2760 				}
  2488 						if ( $the_cat ) {
  2761 
  2489 							$this->set( 'cat', $the_cat->term_id );
  2762 				if ( 'category' === $queried_taxonomy ) {
  2490 							$this->set( 'category_name', $the_cat->slug );
  2763 					$the_cat = get_term_by( $queried_items['field'], $queried_items['terms'][0], 'category' );
  2491 						}
  2764 					if ( $the_cat ) {
  2492 						unset( $the_cat );
  2765 						$this->set( 'cat', $the_cat->term_id );
       
  2766 						$this->set( 'category_name', $the_cat->slug );
  2493 					}
  2767 					}
       
  2768 					unset( $the_cat );
  2494 				}
  2769 				}
  2495 				unset( $cat_query );
  2770 
  2496 
  2771 				if ( 'post_tag' === $queried_taxonomy ) {
  2497 				$tag_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'post_tag' ) );
  2772 					$the_tag = get_term_by( $queried_items['field'], $queried_items['terms'][0], 'post_tag' );
  2498 				if ( ! empty( $tag_query ) ) {
  2773 					if ( $the_tag ) {
  2499 					$tag_query = reset( $tag_query );
  2774 						$this->set( 'tag_id', $the_tag->term_id );
  2500 
       
  2501 					if ( ! empty( $tag_query['terms'][0] ) ) {
       
  2502 						$the_tag = get_term_by( $tag_query['field'], $tag_query['terms'][0], 'post_tag' );
       
  2503 						if ( $the_tag )
       
  2504 							$this->set( 'tag_id', $the_tag->term_id );
       
  2505 						unset( $the_tag );
       
  2506 					}
  2775 					}
       
  2776 					unset( $the_tag );
  2507 				}
  2777 				}
  2508 				unset( $tag_query );
       
  2509 			}
  2778 			}
  2510 		}
  2779 		}
  2511 
  2780 
  2512 		if ( !empty( $this->tax_query->queries ) || !empty( $this->meta_query->queries ) ) {
  2781 		if ( !empty( $this->tax_query->queries ) || !empty( $this->meta_query->queries ) ) {
  2513 			$groupby = "{$wpdb->posts}.ID";
  2782 			$groupby = "{$wpdb->posts}.ID";
  2556 		if ( isset( $q['post_mime_type'] ) && '' != $q['post_mime_type'] )
  2825 		if ( isset( $q['post_mime_type'] ) && '' != $q['post_mime_type'] )
  2557 			$whichmimetype = wp_post_mime_type_where( $q['post_mime_type'], $wpdb->posts );
  2826 			$whichmimetype = wp_post_mime_type_where( $q['post_mime_type'], $wpdb->posts );
  2558 
  2827 
  2559 		$where .= $search . $whichauthor . $whichmimetype;
  2828 		$where .= $search . $whichauthor . $whichmimetype;
  2560 
  2829 
  2561 		if ( empty($q['order']) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC')) )
  2830 		if ( ! empty( $this->meta_query->queries ) ) {
  2562 			$q['order'] = 'DESC';
  2831 			$clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this );
  2563 
  2832 			$join   .= $clauses['join'];
  2564 		// Order by
  2833 			$where  .= $clauses['where'];
  2565 		if ( empty($q['orderby']) ) {
  2834 		}
  2566 			$orderby = "$wpdb->posts.post_date " . $q['order'];
  2835 
       
  2836 		$rand = ( isset( $q['orderby'] ) && 'rand' === $q['orderby'] );
       
  2837 		if ( ! isset( $q['order'] ) ) {
       
  2838 			$q['order'] = $rand ? '' : 'DESC';
       
  2839 		} else {
       
  2840 			$q['order'] = $rand ? '' : $this->parse_order( $q['order'] );
       
  2841 		}
       
  2842 
       
  2843 		// Order by.
       
  2844 		if ( empty( $q['orderby'] ) ) {
       
  2845 			/*
       
  2846 			 * Boolean false or empty array blanks out ORDER BY,
       
  2847 			 * while leaving the value unset or otherwise empty sets the default.
       
  2848 			 */
       
  2849 			if ( isset( $q['orderby'] ) && ( is_array( $q['orderby'] ) || false === $q['orderby'] ) ) {
       
  2850 				$orderby = '';
       
  2851 			} else {
       
  2852 				$orderby = "$wpdb->posts.post_date " . $q['order'];
       
  2853 			}
  2567 		} elseif ( 'none' == $q['orderby'] ) {
  2854 		} elseif ( 'none' == $q['orderby'] ) {
  2568 			$orderby = '';
  2855 			$orderby = '';
  2569 		} elseif ( $q['orderby'] == 'post__in' && ! empty( $post__in ) ) {
  2856 		} elseif ( $q['orderby'] == 'post__in' && ! empty( $post__in ) ) {
  2570 			$orderby = "FIELD( {$wpdb->posts}.ID, $post__in )";
  2857 			$orderby = "FIELD( {$wpdb->posts}.ID, $post__in )";
  2571 		} elseif ( $q['orderby'] == 'post_parent__in' && ! empty( $post_parent__in ) ) {
  2858 		} elseif ( $q['orderby'] == 'post_parent__in' && ! empty( $post_parent__in ) ) {
  2572 			$orderby = "FIELD( {$wpdb->posts}.post_parent, $post_parent__in )";
  2859 			$orderby = "FIELD( {$wpdb->posts}.post_parent, $post_parent__in )";
  2573 		} else {
  2860 		} else {
  2574 			// Used to filter values
       
  2575 			$allowed_keys = array('name', 'author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count');
       
  2576 			if ( !empty($q['meta_key']) ) {
       
  2577 				$allowed_keys[] = $q['meta_key'];
       
  2578 				$allowed_keys[] = 'meta_value';
       
  2579 				$allowed_keys[] = 'meta_value_num';
       
  2580 			}
       
  2581 			$q['orderby'] = urldecode($q['orderby']);
       
  2582 			$q['orderby'] = addslashes_gpc($q['orderby']);
       
  2583 
       
  2584 			$orderby_array = array();
  2861 			$orderby_array = array();
  2585 			foreach ( explode( ' ', $q['orderby'] ) as $i => $orderby ) {
  2862 			if ( is_array( $q['orderby'] ) ) {
  2586 				// Only allow certain values for safety
  2863 				foreach ( $q['orderby'] as $_orderby => $order ) {
  2587 				if ( ! in_array($orderby, $allowed_keys) )
  2864 					$orderby = addslashes_gpc( urldecode( $_orderby ) );
  2588 					continue;
  2865 					$parsed  = $this->parse_orderby( $orderby );
  2589 
  2866 
  2590 				switch ( $orderby ) {
  2867 					if ( ! $parsed ) {
  2591 					case 'menu_order':
  2868 						continue;
  2592 						$orderby = "$wpdb->posts.menu_order";
  2869 					}
  2593 						break;
  2870 
  2594 					case 'ID':
  2871 					$orderby_array[] = $parsed . ' ' . $this->parse_order( $order );
  2595 						$orderby = "$wpdb->posts.ID";
       
  2596 						break;
       
  2597 					case 'rand':
       
  2598 						$orderby = 'RAND()';
       
  2599 						break;
       
  2600 					case $q['meta_key']:
       
  2601 					case 'meta_value':
       
  2602 						if ( isset( $q['meta_type'] ) ) {
       
  2603 							$meta_type = $this->meta_query->get_cast_for_type( $q['meta_type'] );
       
  2604 							$orderby = "CAST($wpdb->postmeta.meta_value AS {$meta_type})";
       
  2605 						} else {
       
  2606 							$orderby = "$wpdb->postmeta.meta_value";
       
  2607 						}
       
  2608 						break;
       
  2609 					case 'meta_value_num':
       
  2610 						$orderby = "$wpdb->postmeta.meta_value+0";
       
  2611 						break;
       
  2612 					case 'comment_count':
       
  2613 						$orderby = "$wpdb->posts.comment_count";
       
  2614 						break;
       
  2615 					default:
       
  2616 						$orderby = "$wpdb->posts.post_" . $orderby;
       
  2617 				}
  2872 				}
  2618 
  2873 				$orderby = implode( ', ', $orderby_array );
  2619 				$orderby_array[] = $orderby;
  2874 
  2620 			}
  2875 			} else {
  2621 			$orderby = implode( ',', $orderby_array );
  2876 				$q['orderby'] = urldecode( $q['orderby'] );
  2622 
  2877 				$q['orderby'] = addslashes_gpc( $q['orderby'] );
  2623 			if ( empty( $orderby ) )
  2878 
  2624 				$orderby = "$wpdb->posts.post_date ".$q['order'];
  2879 				foreach ( explode( ' ', $q['orderby'] ) as $i => $orderby ) {
  2625 			else
  2880 					$parsed = $this->parse_orderby( $orderby );
  2626 				$orderby .= " {$q['order']}";
  2881 					// Only allow certain values for safety.
       
  2882 					if ( ! $parsed ) {
       
  2883 						continue;
       
  2884 					}
       
  2885 
       
  2886 					$orderby_array[] = $parsed;
       
  2887 				}
       
  2888 				$orderby = implode( ' ' . $q['order'] . ', ', $orderby_array );
       
  2889 
       
  2890 				if ( empty( $orderby ) ) {
       
  2891 					$orderby = "$wpdb->posts.post_date " . $q['order'];
       
  2892 				} elseif ( ! empty( $q['order'] ) ) {
       
  2893 					$orderby .= " {$q['order']}";
       
  2894 				}
       
  2895 			}
  2627 		}
  2896 		}
  2628 
  2897 
  2629 		// Order search results by relevance only when another "orderby" is not specified in the query.
  2898 		// Order search results by relevance only when another "orderby" is not specified in the query.
  2630 		if ( ! empty( $q['s'] ) ) {
  2899 		if ( ! empty( $q['s'] ) ) {
  2631 			$search_orderby = '';
  2900 			$search_orderby = '';
  2651 			if ( is_array( $post_type ) )
  2920 			if ( is_array( $post_type ) )
  2652 				$post_type = reset( $post_type );
  2921 				$post_type = reset( $post_type );
  2653 			$post_type_object = get_post_type_object( $post_type );
  2922 			$post_type_object = get_post_type_object( $post_type );
  2654 			if ( empty( $post_type_object ) )
  2923 			if ( empty( $post_type_object ) )
  2655 				$post_type_cap = $post_type;
  2924 				$post_type_cap = $post_type;
       
  2925 		}
       
  2926 
       
  2927 		if ( isset( $q['post_password'] ) ) {
       
  2928 			$where .= $wpdb->prepare( " AND $wpdb->posts.post_password = %s", $q['post_password'] );
       
  2929 			if ( empty( $q['perm'] ) ) {
       
  2930 				$q['perm'] = 'readable';
       
  2931 			}
       
  2932 		} elseif ( isset( $q['has_password'] ) ) {
       
  2933 			$where .= sprintf( " AND $wpdb->posts.post_password %s ''", $q['has_password'] ? '!=' : '=' );
  2656 		}
  2934 		}
  2657 
  2935 
  2658 		if ( 'any' == $post_type ) {
  2936 		if ( 'any' == $post_type ) {
  2659 			$in_search_post_types = get_post_types( array('exclude_from_search' => false) );
  2937 			$in_search_post_types = get_post_types( array('exclude_from_search' => false) );
  2660 			if ( empty( $in_search_post_types ) )
  2938 			if ( empty( $in_search_post_types ) )
  2688 			$read_private_cap = 'read_private_' . $post_type_cap . 's';
  2966 			$read_private_cap = 'read_private_' . $post_type_cap . 's';
  2689 		}
  2967 		}
  2690 
  2968 
  2691 		$user_id = get_current_user_id();
  2969 		$user_id = get_current_user_id();
  2692 
  2970 
       
  2971 		$q_status = array();
  2693 		if ( ! empty( $q['post_status'] ) ) {
  2972 		if ( ! empty( $q['post_status'] ) ) {
  2694 			$statuswheres = array();
  2973 			$statuswheres = array();
  2695 			$q_status = $q['post_status'];
  2974 			$q_status = $q['post_status'];
  2696 			if ( ! is_array( $q_status ) )
  2975 			if ( ! is_array( $q_status ) )
  2697 				$q_status = explode(',', $q_status);
  2976 				$q_status = explode(',', $q_status);
  2698 			$r_status = array();
  2977 			$r_status = array();
  2699 			$p_status = array();
  2978 			$p_status = array();
  2700 			$e_status = array();
  2979 			$e_status = array();
  2701 			if ( in_array('any', $q_status) ) {
  2980 			if ( in_array( 'any', $q_status ) ) {
  2702 				foreach ( get_post_stati( array('exclude_from_search' => true) ) as $status )
  2981 				foreach ( get_post_stati( array( 'exclude_from_search' => true ) ) as $status ) {
  2703 					$e_status[] = "$wpdb->posts.post_status <> '$status'";
  2982 					if ( ! in_array( $status, $q_status ) ) {
       
  2983 						$e_status[] = "$wpdb->posts.post_status <> '$status'";
       
  2984 					}
       
  2985 				}
  2704 			} else {
  2986 			} else {
  2705 				foreach ( get_post_stati() as $status ) {
  2987 				foreach ( get_post_stati() as $status ) {
  2706 					if ( in_array( $status, $q_status ) ) {
  2988 					if ( in_array( $status, $q_status ) ) {
  2707 						if ( 'private' == $status )
  2989 						if ( 'private' == $status )
  2708 							$p_status[] = "$wpdb->posts.post_status = '$status'";
  2990 							$p_status[] = "$wpdb->posts.post_status = '$status'";
  2735 			if ( $post_status_join ) {
  3017 			if ( $post_status_join ) {
  2736 				$join .= " LEFT JOIN $wpdb->posts AS p2 ON ($wpdb->posts.post_parent = p2.ID) ";
  3018 				$join .= " LEFT JOIN $wpdb->posts AS p2 ON ($wpdb->posts.post_parent = p2.ID) ";
  2737 				foreach ( $statuswheres as $index => $statuswhere )
  3019 				foreach ( $statuswheres as $index => $statuswhere )
  2738 					$statuswheres[$index] = "($statuswhere OR ($wpdb->posts.post_status = 'inherit' AND " . str_replace($wpdb->posts, 'p2', $statuswhere) . "))";
  3020 					$statuswheres[$index] = "($statuswhere OR ($wpdb->posts.post_status = 'inherit' AND " . str_replace($wpdb->posts, 'p2', $statuswhere) . "))";
  2739 			}
  3021 			}
  2740 			foreach ( $statuswheres as $statuswhere )
  3022 			$where_status = implode( ' OR ', $statuswheres );
  2741 				$where .= " AND $statuswhere";
  3023 			if ( ! empty( $where_status ) ) {
       
  3024 				$where .= " AND ($where_status)";
       
  3025 			}
  2742 		} elseif ( !$this->is_singular ) {
  3026 		} elseif ( !$this->is_singular ) {
  2743 			$where .= " AND ($wpdb->posts.post_status = 'publish'";
  3027 			$where .= " AND ($wpdb->posts.post_status = 'publish'";
  2744 
  3028 
  2745 			// Add public states.
  3029 			// Add public states.
  2746 			$public_states = get_post_stati( array('public' => true) );
  3030 			$public_states = get_post_stati( array('public' => true) );
  2765 			}
  3049 			}
  2766 
  3050 
  2767 			$where .= ')';
  3051 			$where .= ')';
  2768 		}
  3052 		}
  2769 
  3053 
  2770 		if ( !empty( $this->meta_query->queries ) ) {
  3054 		/*
  2771 			$clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this );
  3055 		 * Apply filters on where and join prior to paging so that any
  2772 			$join .= $clauses['join'];
  3056 		 * manipulations to them are reflected in the paging by day queries.
  2773 			$where .= $clauses['where'];
  3057 		 */
  2774 		}
       
  2775 
       
  2776 		// Apply filters on where and join prior to paging so that any
       
  2777 		// manipulations to them are reflected in the paging by day queries.
       
  2778 		if ( !$q['suppress_filters'] ) {
  3058 		if ( !$q['suppress_filters'] ) {
  2779 			$where = apply_filters_ref_array('posts_where', array( $where, &$this ) );
  3059 			/**
  2780 			$join = apply_filters_ref_array('posts_join', array( $join, &$this ) );
  3060 			 * Filter the WHERE clause of the query.
       
  3061 			 *
       
  3062 			 * @since 1.5.0
       
  3063 			 *
       
  3064 			 * @param string   $where The WHERE clause of the query.
       
  3065 			 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3066 			 */
       
  3067 			$where = apply_filters_ref_array( 'posts_where', array( $where, &$this ) );
       
  3068 
       
  3069 			/**
       
  3070 			 * Filter the JOIN clause of the query.
       
  3071 			 *
       
  3072 			 * @since 1.5.0
       
  3073 			 *
       
  3074 			 * @param string   $where The JOIN clause of the query.
       
  3075 			 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3076 			 */
       
  3077 			$join = apply_filters_ref_array( 'posts_join', array( $join, &$this ) );
  2781 		}
  3078 		}
  2782 
  3079 
  2783 		// Paging
  3080 		// Paging
  2784 		if ( empty($q['nopaging']) && !$this->is_singular ) {
  3081 		if ( empty($q['nopaging']) && !$this->is_singular ) {
  2785 			$page = absint($q['paged']);
  3082 			$page = absint($q['paged']);
  2786 			if ( !$page )
  3083 			if ( !$page )
  2787 				$page = 1;
  3084 				$page = 1;
  2788 
  3085 
  2789 			if ( empty($q['offset']) ) {
  3086 			if ( empty($q['offset']) ) {
  2790 				$pgstrt = ($page - 1) * $q['posts_per_page'] . ', ';
  3087 				$pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
  2791 			} else { // we're ignoring $page and using 'offset'
  3088 			} else { // we're ignoring $page and using 'offset'
  2792 				$q['offset'] = absint($q['offset']);
  3089 				$q['offset'] = absint($q['offset']);
  2793 				$pgstrt = $q['offset'] . ', ';
  3090 				$pgstrt = $q['offset'] . ', ';
  2794 			}
  3091 			}
  2795 			$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
  3092 			$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
  2796 		}
  3093 		}
  2797 
  3094 
  2798 		// Comments feeds
  3095 		// Comments feeds
  2799 		if ( $this->is_comment_feed && ( $this->is_archive || $this->is_search || !$this->is_singular ) ) {
  3096 		if ( $this->is_comment_feed && ! $this->is_singular ) {
  2800 			if ( $this->is_archive || $this->is_search ) {
  3097 			if ( $this->is_archive || $this->is_search ) {
  2801 				$cjoin = "JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) $join ";
  3098 				$cjoin = "JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) $join ";
  2802 				$cwhere = "WHERE comment_approved = '1' $where";
  3099 				$cwhere = "WHERE comment_approved = '1' $where";
  2803 				$cgroupby = "$wpdb->comments.comment_id";
  3100 				$cgroupby = "$wpdb->comments.comment_id";
  2804 			} else { // Other non singular e.g. front
  3101 			} else { // Other non singular e.g. front
  2806 				$cwhere = "WHERE post_status = 'publish' AND comment_approved = '1'";
  3103 				$cwhere = "WHERE post_status = 'publish' AND comment_approved = '1'";
  2807 				$cgroupby = '';
  3104 				$cgroupby = '';
  2808 			}
  3105 			}
  2809 
  3106 
  2810 			if ( !$q['suppress_filters'] ) {
  3107 			if ( !$q['suppress_filters'] ) {
  2811 				$cjoin = apply_filters_ref_array('comment_feed_join', array( $cjoin, &$this ) );
  3108 				/**
  2812 				$cwhere = apply_filters_ref_array('comment_feed_where', array( $cwhere, &$this ) );
  3109 				 * Filter the JOIN clause of the comments feed query before sending.
  2813 				$cgroupby = apply_filters_ref_array('comment_feed_groupby', array( $cgroupby, &$this ) );
  3110 				 *
  2814 				$corderby = apply_filters_ref_array('comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
  3111 				 * @since 2.2.0
  2815 				$climits = apply_filters_ref_array('comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );
  3112 				 *
       
  3113 				 * @param string   $cjoin The JOIN clause of the query.
       
  3114 				 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3115 				 */
       
  3116 				$cjoin = apply_filters_ref_array( 'comment_feed_join', array( $cjoin, &$this ) );
       
  3117 
       
  3118 				/**
       
  3119 				 * Filter the WHERE clause of the comments feed query before sending.
       
  3120 				 *
       
  3121 				 * @since 2.2.0
       
  3122 				 *
       
  3123 				 * @param string   $cwhere The WHERE clause of the query.
       
  3124 				 * @param WP_Query &$this  The WP_Query instance (passed by reference).
       
  3125 				 */
       
  3126 				$cwhere = apply_filters_ref_array( 'comment_feed_where', array( $cwhere, &$this ) );
       
  3127 
       
  3128 				/**
       
  3129 				 * Filter the GROUP BY clause of the comments feed query before sending.
       
  3130 				 *
       
  3131 				 * @since 2.2.0
       
  3132 				 *
       
  3133 				 * @param string   $cgroupby The GROUP BY clause of the query.
       
  3134 				 * @param WP_Query &$this    The WP_Query instance (passed by reference).
       
  3135 				 */
       
  3136 				$cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( $cgroupby, &$this ) );
       
  3137 
       
  3138 				/**
       
  3139 				 * Filter the ORDER BY clause of the comments feed query before sending.
       
  3140 				 *
       
  3141 				 * @since 2.8.0
       
  3142 				 *
       
  3143 				 * @param string   $corderby The ORDER BY clause of the query.
       
  3144 				 * @param WP_Query &$this    The WP_Query instance (passed by reference).
       
  3145 				 */
       
  3146 				$corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
       
  3147 
       
  3148 				/**
       
  3149 				 * Filter the LIMIT clause of the comments feed query before sending.
       
  3150 				 *
       
  3151 				 * @since 2.8.0
       
  3152 				 *
       
  3153 				 * @param string   $climits The JOIN clause of the query.
       
  3154 				 * @param WP_Query &$this   The WP_Query instance (passed by reference).
       
  3155 				 */
       
  3156 				$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );
  2816 			}
  3157 			}
  2817 			$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
  3158 			$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
  2818 			$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
  3159 			$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
  2819 
  3160 
  2820 			$this->comments = (array) $wpdb->get_results("SELECT $distinct $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits");
  3161 			$this->comments = (array) $wpdb->get_results("SELECT $distinct $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits");
  2833 				$where = "AND 0";
  3174 				$where = "AND 0";
  2834 		}
  3175 		}
  2835 
  3176 
  2836 		$pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' );
  3177 		$pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' );
  2837 
  3178 
  2838 		// Apply post-paging filters on where and join. Only plugins that
  3179 		/*
  2839 		// manipulate paging queries should use these hooks.
  3180 		 * Apply post-paging filters on where and join. Only plugins that
       
  3181 		 * manipulate paging queries should use these hooks.
       
  3182 		 */
  2840 		if ( !$q['suppress_filters'] ) {
  3183 		if ( !$q['suppress_filters'] ) {
  2841 			$where		= apply_filters_ref_array( 'posts_where_paged',	array( $where, &$this ) );
  3184 			/**
  2842 			$groupby	= apply_filters_ref_array( 'posts_groupby',		array( $groupby, &$this ) );
  3185 			 * Filter the WHERE clause of the query.
  2843 			$join		= apply_filters_ref_array( 'posts_join_paged',	array( $join, &$this ) );
  3186 			 *
  2844 			$orderby	= apply_filters_ref_array( 'posts_orderby',		array( $orderby, &$this ) );
  3187 			 * Specifically for manipulating paging queries.
  2845 			$distinct	= apply_filters_ref_array( 'posts_distinct',	array( $distinct, &$this ) );
  3188 			 *
  2846 			$limits		= apply_filters_ref_array( 'post_limits',		array( $limits, &$this ) );
  3189 			 * @since 1.5.0
  2847 			$fields		= apply_filters_ref_array( 'posts_fields',		array( $fields, &$this ) );
  3190 			 *
  2848 
  3191 			 * @param string   $where The WHERE clause of the query.
  2849 			// Filter all clauses at once, for convenience
  3192 			 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3193 			 */
       
  3194 			$where = apply_filters_ref_array( 'posts_where_paged', array( $where, &$this ) );
       
  3195 
       
  3196 			/**
       
  3197 			 * Filter the GROUP BY clause of the query.
       
  3198 			 *
       
  3199 			 * @since 2.0.0
       
  3200 			 *
       
  3201 			 * @param string   $groupby The GROUP BY clause of the query.
       
  3202 			 * @param WP_Query &$this   The WP_Query instance (passed by reference).
       
  3203 			 */
       
  3204 			$groupby = apply_filters_ref_array( 'posts_groupby', array( $groupby, &$this ) );
       
  3205 
       
  3206 			/**
       
  3207 			 * Filter the JOIN clause of the query.
       
  3208 			 *
       
  3209 			 * Specifically for manipulating paging queries.
       
  3210 			 *
       
  3211 			 * @since 1.5.0
       
  3212 			 *
       
  3213 			 * @param string   $join  The JOIN clause of the query.
       
  3214 			 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3215 			 */
       
  3216 			$join = apply_filters_ref_array( 'posts_join_paged', array( $join, &$this ) );
       
  3217 
       
  3218 			/**
       
  3219 			 * Filter the ORDER BY clause of the query.
       
  3220 			 *
       
  3221 			 * @since 1.5.1
       
  3222 			 *
       
  3223 			 * @param string   $orderby The ORDER BY clause of the query.
       
  3224 			 * @param WP_Query &$this   The WP_Query instance (passed by reference).
       
  3225 			 */
       
  3226 			$orderby = apply_filters_ref_array( 'posts_orderby', array( $orderby, &$this ) );
       
  3227 
       
  3228 			/**
       
  3229 			 * Filter the DISTINCT clause of the query.
       
  3230 			 *
       
  3231 			 * @since 2.1.0
       
  3232 			 *
       
  3233 			 * @param string   $distinct The DISTINCT clause of the query.
       
  3234 			 * @param WP_Query &$this    The WP_Query instance (passed by reference).
       
  3235 			 */
       
  3236 			$distinct = apply_filters_ref_array( 'posts_distinct', array( $distinct, &$this ) );
       
  3237 
       
  3238 			/**
       
  3239 			 * Filter the LIMIT clause of the query.
       
  3240 			 *
       
  3241 			 * @since 2.1.0
       
  3242 			 *
       
  3243 			 * @param string   $limits The LIMIT clause of the query.
       
  3244 			 * @param WP_Query &$this  The WP_Query instance (passed by reference).
       
  3245 			 */
       
  3246 			$limits = apply_filters_ref_array( 'post_limits', array( $limits, &$this ) );
       
  3247 
       
  3248 			/**
       
  3249 			 * Filter the SELECT clause of the query.
       
  3250 			 *
       
  3251 			 * @since 2.1.0
       
  3252 			 *
       
  3253 			 * @param string   $fields The SELECT clause of the query.
       
  3254 			 * @param WP_Query &$this  The WP_Query instance (passed by reference).
       
  3255 			 */
       
  3256 			$fields = apply_filters_ref_array( 'posts_fields', array( $fields, &$this ) );
       
  3257 
       
  3258 			/**
       
  3259 			 * Filter all query clauses at once, for convenience.
       
  3260 			 *
       
  3261 			 * Covers the WHERE, GROUP BY, JOIN, ORDER BY, DISTINCT,
       
  3262 			 * fields (SELECT), and LIMITS clauses.
       
  3263 			 *
       
  3264 			 * @since 3.1.0
       
  3265 			 *
       
  3266 			 * @param array    $clauses The list of clauses for the query.
       
  3267 			 * @param WP_Query &$this   The WP_Query instance (passed by reference).
       
  3268 			 */
  2850 			$clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) );
  3269 			$clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) );
  2851 			foreach ( $pieces as $piece )
  3270 
  2852 				$$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';
  3271 			$where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
  2853 		}
  3272 			$groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : '';
  2854 
  3273 			$join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
  2855 		// Announce current selection parameters. For use by caching plugins.
  3274 			$orderby = isset( $clauses[ 'orderby' ] ) ? $clauses[ 'orderby' ] : '';
       
  3275 			$distinct = isset( $clauses[ 'distinct' ] ) ? $clauses[ 'distinct' ] : '';
       
  3276 			$fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : '';
       
  3277 			$limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : '';
       
  3278 		}
       
  3279 
       
  3280 		/**
       
  3281 		 * Fires to announce the query's current selection parameters.
       
  3282 		 *
       
  3283 		 * For use by caching plugins.
       
  3284 		 *
       
  3285 		 * @since 2.3.0
       
  3286 		 *
       
  3287 		 * @param string $selection The assembled selection query.
       
  3288 		 */
  2856 		do_action( 'posts_selection', $where . $groupby . $orderby . $limits . $join );
  3289 		do_action( 'posts_selection', $where . $groupby . $orderby . $limits . $join );
  2857 
  3290 
  2858 		// Filter again for the benefit of caching plugins. Regular plugins should use the hooks above.
  3291 		/*
       
  3292 		 * Filter again for the benefit of caching plugins.
       
  3293 		 * Regular plugins should use the hooks above.
       
  3294 		 */
  2859 		if ( !$q['suppress_filters'] ) {
  3295 		if ( !$q['suppress_filters'] ) {
  2860 			$where		= apply_filters_ref_array( 'posts_where_request',		array( $where, &$this ) );
  3296 			/**
  2861 			$groupby	= apply_filters_ref_array( 'posts_groupby_request',		array( $groupby, &$this ) );
  3297 			 * Filter the WHERE clause of the query.
  2862 			$join		= apply_filters_ref_array( 'posts_join_request',		array( $join, &$this ) );
  3298 			 *
  2863 			$orderby	= apply_filters_ref_array( 'posts_orderby_request',		array( $orderby, &$this ) );
  3299 			 * For use by caching plugins.
  2864 			$distinct	= apply_filters_ref_array( 'posts_distinct_request',	array( $distinct, &$this ) );
  3300 			 *
  2865 			$fields		= apply_filters_ref_array( 'posts_fields_request',		array( $fields, &$this ) );
  3301 			 * @since 2.5.0
  2866 			$limits		= apply_filters_ref_array( 'post_limits_request',		array( $limits, &$this ) );
  3302 			 *
  2867 
  3303 			 * @param string   $where The WHERE clause of the query.
  2868 			// Filter all clauses at once, for convenience
  3304 			 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3305 			 */
       
  3306 			$where = apply_filters_ref_array( 'posts_where_request', array( $where, &$this ) );
       
  3307 
       
  3308 			/**
       
  3309 			 * Filter the GROUP BY clause of the query.
       
  3310 			 *
       
  3311 			 * For use by caching plugins.
       
  3312 			 *
       
  3313 			 * @since 2.5.0
       
  3314 			 *
       
  3315 			 * @param string   $groupby The GROUP BY clause of the query.
       
  3316 			 * @param WP_Query &$this   The WP_Query instance (passed by reference).
       
  3317 			 */
       
  3318 			$groupby = apply_filters_ref_array( 'posts_groupby_request', array( $groupby, &$this ) );
       
  3319 
       
  3320 			/**
       
  3321 			 * Filter the JOIN clause of the query.
       
  3322 			 *
       
  3323 			 * For use by caching plugins.
       
  3324 			 *
       
  3325 			 * @since 2.5.0
       
  3326 			 *
       
  3327 			 * @param string   $join  The JOIN clause of the query.
       
  3328 			 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3329 			 */
       
  3330 			$join = apply_filters_ref_array( 'posts_join_request', array( $join, &$this ) );
       
  3331 
       
  3332 			/**
       
  3333 			 * Filter the ORDER BY clause of the query.
       
  3334 			 *
       
  3335 			 * For use by caching plugins.
       
  3336 			 *
       
  3337 			 * @since 2.5.0
       
  3338 			 *
       
  3339 			 * @param string   $orderby The ORDER BY clause of the query.
       
  3340 			 * @param WP_Query &$this   The WP_Query instance (passed by reference).
       
  3341 			 */
       
  3342 			$orderby = apply_filters_ref_array( 'posts_orderby_request', array( $orderby, &$this ) );
       
  3343 
       
  3344 			/**
       
  3345 			 * Filter the DISTINCT clause of the query.
       
  3346 			 *
       
  3347 			 * For use by caching plugins.
       
  3348 			 *
       
  3349 			 * @since 2.5.0
       
  3350 			 *
       
  3351 			 * @param string   $distinct The DISTINCT clause of the query.
       
  3352 			 * @param WP_Query &$this    The WP_Query instance (passed by reference).
       
  3353 			 */
       
  3354 			$distinct = apply_filters_ref_array( 'posts_distinct_request', array( $distinct, &$this ) );
       
  3355 
       
  3356 			/**
       
  3357 			 * Filter the SELECT clause of the query.
       
  3358 			 *
       
  3359 			 * For use by caching plugins.
       
  3360 			 *
       
  3361 			 * @since 2.5.0
       
  3362 			 *
       
  3363 			 * @param string   $fields The SELECT clause of the query.
       
  3364 			 * @param WP_Query &$this  The WP_Query instance (passed by reference).
       
  3365 			 */
       
  3366 			$fields = apply_filters_ref_array( 'posts_fields_request', array( $fields, &$this ) );
       
  3367 
       
  3368 			/**
       
  3369 			 * Filter the LIMIT clause of the query.
       
  3370 			 *
       
  3371 			 * For use by caching plugins.
       
  3372 			 *
       
  3373 			 * @since 2.5.0
       
  3374 			 *
       
  3375 			 * @param string   $limits The LIMIT clause of the query.
       
  3376 			 * @param WP_Query &$this  The WP_Query instance (passed by reference).
       
  3377 			 */
       
  3378 			$limits = apply_filters_ref_array( 'post_limits_request', array( $limits, &$this ) );
       
  3379 
       
  3380 			/**
       
  3381 			 * Filter all query clauses at once, for convenience.
       
  3382 			 *
       
  3383 			 * For use by caching plugins.
       
  3384 			 *
       
  3385 			 * Covers the WHERE, GROUP BY, JOIN, ORDER BY, DISTINCT,
       
  3386 			 * fields (SELECT), and LIMITS clauses.
       
  3387 			 *
       
  3388 			 * @since 3.1.0
       
  3389 			 *
       
  3390 			 * @param array    $pieces The pieces of the query.
       
  3391 			 * @param WP_Query &$this  The WP_Query instance (passed by reference).
       
  3392 			 */
  2869 			$clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) );
  3393 			$clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) );
  2870 			foreach ( $pieces as $piece )
  3394 
  2871 				$$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';
  3395 			$where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
       
  3396 			$groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : '';
       
  3397 			$join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
       
  3398 			$orderby = isset( $clauses[ 'orderby' ] ) ? $clauses[ 'orderby' ] : '';
       
  3399 			$distinct = isset( $clauses[ 'distinct' ] ) ? $clauses[ 'distinct' ] : '';
       
  3400 			$fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : '';
       
  3401 			$limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : '';
  2872 		}
  3402 		}
  2873 
  3403 
  2874 		if ( ! empty($groupby) )
  3404 		if ( ! empty($groupby) )
  2875 			$groupby = 'GROUP BY ' . $groupby;
  3405 			$groupby = 'GROUP BY ' . $groupby;
  2876 		if ( !empty( $orderby ) )
  3406 		if ( !empty( $orderby ) )
  2881 			$found_rows = 'SQL_CALC_FOUND_ROWS';
  3411 			$found_rows = 'SQL_CALC_FOUND_ROWS';
  2882 
  3412 
  2883 		$this->request = $old_request = "SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits";
  3413 		$this->request = $old_request = "SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits";
  2884 
  3414 
  2885 		if ( !$q['suppress_filters'] ) {
  3415 		if ( !$q['suppress_filters'] ) {
       
  3416 			/**
       
  3417 			 * Filter the completed SQL query before sending.
       
  3418 			 *
       
  3419 			 * @since 2.0.0
       
  3420 			 *
       
  3421 			 * @param array    $request The complete SQL query.
       
  3422 			 * @param WP_Query &$this   The WP_Query instance (passed by reference).
       
  3423 			 */
  2886 			$this->request = apply_filters_ref_array( 'posts_request', array( $this->request, &$this ) );
  3424 			$this->request = apply_filters_ref_array( 'posts_request', array( $this->request, &$this ) );
  2887 		}
  3425 		}
  2888 
  3426 
  2889 		if ( 'ids' == $q['fields'] ) {
  3427 		if ( 'ids' == $q['fields'] ) {
  2890 			$this->posts = $wpdb->get_col( $this->request );
  3428 			$this->posts = $wpdb->get_col( $this->request );
       
  3429 			$this->posts = array_map( 'intval', $this->posts );
  2891 			$this->post_count = count( $this->posts );
  3430 			$this->post_count = count( $this->posts );
  2892 			$this->set_found_posts( $q, $limits );
  3431 			$this->set_found_posts( $q, $limits );
  2893 
  3432 
  2894 			return $this->posts;
  3433 			return $this->posts;
  2895 		}
  3434 		}
  2898 			$this->posts = $wpdb->get_results( $this->request );
  3437 			$this->posts = $wpdb->get_results( $this->request );
  2899 			$this->post_count = count( $this->posts );
  3438 			$this->post_count = count( $this->posts );
  2900 			$this->set_found_posts( $q, $limits );
  3439 			$this->set_found_posts( $q, $limits );
  2901 
  3440 
  2902 			$r = array();
  3441 			$r = array();
  2903 			foreach ( $this->posts as $post )
  3442 			foreach ( $this->posts as $key => $post ) {
  2904 				$r[ $post->ID ] = $post->post_parent;
  3443 				$this->posts[ $key ]->ID = (int) $post->ID;
       
  3444 				$this->posts[ $key ]->post_parent = (int) $post->post_parent;
       
  3445 
       
  3446 				$r[ (int) $post->ID ] = (int) $post->post_parent;
       
  3447 			}
  2905 
  3448 
  2906 			return $r;
  3449 			return $r;
  2907 		}
  3450 		}
  2908 
  3451 
  2909 		$split_the_query = ( $old_request == $this->request && "$wpdb->posts.*" == $fields && !empty( $limits ) && $q['posts_per_page'] < 500 );
  3452 		$split_the_query = ( $old_request == $this->request && "$wpdb->posts.*" == $fields && !empty( $limits ) && $q['posts_per_page'] < 500 );
       
  3453 
       
  3454 		/**
       
  3455 		 * Filter whether to split the query.
       
  3456 		 *
       
  3457 		 * Splitting the query will cause it to fetch just the IDs of the found posts
       
  3458 		 * (and then individually fetch each post by ID), rather than fetching every
       
  3459 		 * complete row at once. One massive result vs. many small results.
       
  3460 		 *
       
  3461 		 * @since 3.4.0
       
  3462 		 *
       
  3463 		 * @param bool     $split_the_query Whether or not to split the query.
       
  3464 		 * @param WP_Query $this            The WP_Query instance.
       
  3465 		 */
  2910 		$split_the_query = apply_filters( 'split_the_query', $split_the_query, $this );
  3466 		$split_the_query = apply_filters( 'split_the_query', $split_the_query, $this );
  2911 
  3467 
  2912 		if ( $split_the_query ) {
  3468 		if ( $split_the_query ) {
  2913 			// First get the IDs and then fill in the objects
  3469 			// First get the IDs and then fill in the objects
  2914 
  3470 
  2915 			$this->request = "SELECT $found_rows $distinct $wpdb->posts.ID FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits";
  3471 			$this->request = "SELECT $found_rows $distinct $wpdb->posts.ID FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits";
  2916 
  3472 
       
  3473 			/**
       
  3474 			 * Filter the Post IDs SQL request before sending.
       
  3475 			 *
       
  3476 			 * @since 3.4.0
       
  3477 			 *
       
  3478 			 * @param string   $request The post ID request.
       
  3479 			 * @param WP_Query $this    The WP_Query instance.
       
  3480 			 */
  2917 			$this->request = apply_filters( 'posts_request_ids', $this->request, $this );
  3481 			$this->request = apply_filters( 'posts_request_ids', $this->request, $this );
  2918 
  3482 
  2919 			$ids = $wpdb->get_col( $this->request );
  3483 			$ids = $wpdb->get_col( $this->request );
  2920 
  3484 
  2921 			if ( $ids ) {
  3485 			if ( $ids ) {
  2932 
  3496 
  2933 		// Convert to WP_Post objects
  3497 		// Convert to WP_Post objects
  2934 		if ( $this->posts )
  3498 		if ( $this->posts )
  2935 			$this->posts = array_map( 'get_post', $this->posts );
  3499 			$this->posts = array_map( 'get_post', $this->posts );
  2936 
  3500 
  2937 		// Raw results filter. Prior to status checks.
  3501 		if ( ! $q['suppress_filters'] ) {
  2938 		if ( !$q['suppress_filters'] )
  3502 			/**
  2939 			$this->posts = apply_filters_ref_array('posts_results', array( $this->posts, &$this ) );
  3503 			 * Filter the raw post results array, prior to status checks.
       
  3504 			 *
       
  3505 			 * @since 2.3.0
       
  3506 			 *
       
  3507 			 * @param array    $posts The post results array.
       
  3508 			 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3509 			 */
       
  3510 			$this->posts = apply_filters_ref_array( 'posts_results', array( $this->posts, &$this ) );
       
  3511 		}
  2940 
  3512 
  2941 		if ( !empty($this->posts) && $this->is_comment_feed && $this->is_singular ) {
  3513 		if ( !empty($this->posts) && $this->is_comment_feed && $this->is_singular ) {
  2942 			$cjoin = apply_filters_ref_array('comment_feed_join', array( '', &$this ) );
  3514 			/** This filter is documented in wp-includes/query.php */
  2943 			$cwhere = apply_filters_ref_array('comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) );
  3515 			$cjoin = apply_filters_ref_array( 'comment_feed_join', array( '', &$this ) );
  2944 			$cgroupby = apply_filters_ref_array('comment_feed_groupby', array( '', &$this ) );
  3516 
       
  3517 			/** This filter is documented in wp-includes/query.php */
       
  3518 			$cwhere = apply_filters_ref_array( 'comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) );
       
  3519 
       
  3520 			/** This filter is documented in wp-includes/query.php */
       
  3521 			$cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( '', &$this ) );
  2945 			$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
  3522 			$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
  2946 			$corderby = apply_filters_ref_array('comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
  3523 
       
  3524 			/** This filter is documented in wp-includes/query.php */
       
  3525 			$corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
  2947 			$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
  3526 			$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
  2948 			$climits = apply_filters_ref_array('comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );
  3527 
       
  3528 			/** This filter is documented in wp-includes/query.php */
       
  3529 			$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );
       
  3530 
  2949 			$comments_request = "SELECT $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits";
  3531 			$comments_request = "SELECT $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits";
  2950 			$this->comments = $wpdb->get_results($comments_request);
  3532 			$this->comments = $wpdb->get_results($comments_request);
  2951 			$this->comment_count = count($this->comments);
  3533 			$this->comment_count = count($this->comments);
  2952 		}
  3534 		}
  2953 
  3535 
  2954 		// Check post status to determine if post should be displayed.
  3536 		// Check post status to determine if post should be displayed.
  2955 		if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
  3537 		if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
  2956 			$status = get_post_status($this->posts[0]);
  3538 			$status = get_post_status($this->posts[0]);
  2957 			$post_status_obj = get_post_status_object($status);
  3539 			$post_status_obj = get_post_status_object($status);
  2958 			//$type = get_post_type($this->posts[0]);
  3540 			//$type = get_post_type($this->posts[0]);
  2959 			if ( !$post_status_obj->public ) {
  3541 
       
  3542 			// If the post_status was specifically requested, let it pass through.
       
  3543 			if ( !$post_status_obj->public && ! in_array( $status, $q_status ) ) {
       
  3544 
  2960 				if ( ! is_user_logged_in() ) {
  3545 				if ( ! is_user_logged_in() ) {
  2961 					// User must be logged in to view unpublished posts.
  3546 					// User must be logged in to view unpublished posts.
  2962 					$this->posts = array();
  3547 					$this->posts = array();
  2963 				} else {
  3548 				} else {
  2964 					if  ( $post_status_obj->protected ) {
  3549 					if  ( $post_status_obj->protected ) {
  2977 						$this->posts = array();
  3562 						$this->posts = array();
  2978 					}
  3563 					}
  2979 				}
  3564 				}
  2980 			}
  3565 			}
  2981 
  3566 
  2982 			if ( $this->is_preview && $this->posts && current_user_can( $edit_cap, $this->posts[0]->ID ) )
  3567 			if ( $this->is_preview && $this->posts && current_user_can( $edit_cap, $this->posts[0]->ID ) ) {
       
  3568 				/**
       
  3569 				 * Filter the single post for preview mode.
       
  3570 				 *
       
  3571 				 * @since 2.7.0
       
  3572 				 *
       
  3573 				 * @param WP_Post  $post_preview  The Post object.
       
  3574 				 * @param WP_Query &$this         The WP_Query instance (passed by reference).
       
  3575 				 */
  2983 				$this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) );
  3576 				$this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) );
       
  3577 			}
  2984 		}
  3578 		}
  2985 
  3579 
  2986 		// Put sticky posts at the top of the posts array
  3580 		// Put sticky posts at the top of the posts array
  2987 		$sticky_posts = get_option('sticky_posts');
  3581 		$sticky_posts = get_option('sticky_posts');
  2988 		if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
  3582 		if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
  3022 					$sticky_offset++;
  3616 					$sticky_offset++;
  3023 				}
  3617 				}
  3024 			}
  3618 			}
  3025 		}
  3619 		}
  3026 
  3620 
  3027 		if ( !$q['suppress_filters'] )
  3621 		if ( ! $q['suppress_filters'] ) {
  3028 			$this->posts = apply_filters_ref_array('the_posts', array( $this->posts, &$this ) );
  3622 			/**
       
  3623 			 * Filter the array of retrieved posts after they've been fetched and
       
  3624 			 * internally processed.
       
  3625 			 *
       
  3626 			 * @since 1.5.0
       
  3627 			 *
       
  3628 			 * @param array    $posts The array of retrieved posts.
       
  3629 			 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3630 			 */
       
  3631 			$this->posts = apply_filters_ref_array( 'the_posts', array( $this->posts, &$this ) );
       
  3632 		}
  3029 
  3633 
  3030 		// Ensure that any posts added/modified via one of the filters above are
  3634 		// Ensure that any posts added/modified via one of the filters above are
  3031 		// of the type WP_Post and are filtered.
  3635 		// of the type WP_Post and are filtered.
  3032 		if ( $this->posts ) {
  3636 		if ( $this->posts ) {
  3033 			$this->post_count = count( $this->posts );
  3637 			$this->post_count = count( $this->posts );
  3051 	 * for the current query.
  3655 	 * for the current query.
  3052 	 *
  3656 	 *
  3053 	 * @since 3.5.0
  3657 	 * @since 3.5.0
  3054 	 * @access private
  3658 	 * @access private
  3055 	 */
  3659 	 */
  3056 	function set_found_posts( $q, $limits ) {
  3660 	private function set_found_posts( $q, $limits ) {
  3057 		global $wpdb;
  3661 		global $wpdb;
  3058 
  3662 
  3059 		// Bail if posts is an empty array. Continue if posts is an empty string,
  3663 		// Bail if posts is an empty array. Continue if posts is an empty string,
  3060 		// null, or false to accommodate caching plugins that fill posts later.
  3664 		// null, or false to accommodate caching plugins that fill posts later.
  3061 		if ( $q['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) )
  3665 		if ( $q['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) )
  3062 			return;
  3666 			return;
  3063 
  3667 
  3064 		if ( ! empty( $limits ) )
  3668 		if ( ! empty( $limits ) ) {
       
  3669 			/**
       
  3670 			 * Filter the query to run for retrieving the found posts.
       
  3671 			 *
       
  3672 			 * @since 2.1.0
       
  3673 			 *
       
  3674 			 * @param string   $found_posts The query to run to find the found posts.
       
  3675 			 * @param WP_Query &$this       The WP_Query instance (passed by reference).
       
  3676 			 */
  3065 			$this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) );
  3677 			$this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) );
  3066 		else
  3678 		} else {
  3067 			$this->found_posts = count( $this->posts );
  3679 			$this->found_posts = count( $this->posts );
  3068 
  3680 		}
       
  3681 
       
  3682 		/**
       
  3683 		 * Filter the number of found posts for the query.
       
  3684 		 *
       
  3685 		 * @since 2.1.0
       
  3686 		 *
       
  3687 		 * @param int      $found_posts The number of posts found.
       
  3688 		 * @param WP_Query &$this       The WP_Query instance (passed by reference).
       
  3689 		 */
  3069 		$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
  3690 		$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
  3070 
  3691 
  3071 		if ( ! empty( $limits ) )
  3692 		if ( ! empty( $limits ) )
  3072 			$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
  3693 			$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
  3073 	}
  3694 	}
  3078 	 * @since 1.5.0
  3699 	 * @since 1.5.0
  3079 	 * @access public
  3700 	 * @access public
  3080 	 *
  3701 	 *
  3081 	 * @return WP_Post Next post.
  3702 	 * @return WP_Post Next post.
  3082 	 */
  3703 	 */
  3083 	function next_post() {
  3704 	public function next_post() {
  3084 
  3705 
  3085 		$this->current_post++;
  3706 		$this->current_post++;
  3086 
  3707 
  3087 		$this->post = $this->posts[$this->current_post];
  3708 		$this->post = $this->posts[$this->current_post];
  3088 		return $this->post;
  3709 		return $this->post;
  3094 	 * Retrieves the next post, sets up the post, sets the 'in the loop'
  3715 	 * Retrieves the next post, sets up the post, sets the 'in the loop'
  3095 	 * property to true.
  3716 	 * property to true.
  3096 	 *
  3717 	 *
  3097 	 * @since 1.5.0
  3718 	 * @since 1.5.0
  3098 	 * @access public
  3719 	 * @access public
  3099 	 * @uses $post
  3720 	 */
  3100 	 * @uses do_action_ref_array() Calls 'loop_start' if loop has just started
  3721 	public function the_post() {
  3101 	 */
       
  3102 	function the_post() {
       
  3103 		global $post;
  3722 		global $post;
  3104 		$this->in_the_loop = true;
  3723 		$this->in_the_loop = true;
  3105 
  3724 
  3106 		if ( $this->current_post == -1 ) // loop has just started
  3725 		if ( $this->current_post == -1 ) // loop has just started
  3107 			do_action_ref_array('loop_start', array(&$this));
  3726 			/**
       
  3727 			 * Fires once the loop is started.
       
  3728 			 *
       
  3729 			 * @since 2.0.0
       
  3730 			 *
       
  3731 			 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3732 			 */
       
  3733 			do_action_ref_array( 'loop_start', array( &$this ) );
  3108 
  3734 
  3109 		$post = $this->next_post();
  3735 		$post = $this->next_post();
  3110 		setup_postdata($post);
  3736 		$this->setup_postdata( $post );
  3111 	}
  3737 	}
  3112 
  3738 
  3113 	/**
  3739 	/**
  3114 	 * Whether there are more posts available in the loop.
  3740 	 * Whether there are more posts available in the loop.
  3115 	 *
  3741 	 *
  3116 	 * Calls action 'loop_end', when the loop is complete.
  3742 	 * Calls action 'loop_end', when the loop is complete.
  3117 	 *
  3743 	 *
  3118 	 * @since 1.5.0
  3744 	 * @since 1.5.0
  3119 	 * @access public
  3745 	 * @access public
  3120 	 * @uses do_action_ref_array() Calls 'loop_end' if loop is ended
       
  3121 	 *
  3746 	 *
  3122 	 * @return bool True if posts are available, false if end of loop.
  3747 	 * @return bool True if posts are available, false if end of loop.
  3123 	 */
  3748 	 */
  3124 	function have_posts() {
  3749 	public function have_posts() {
  3125 		if ( $this->current_post + 1 < $this->post_count ) {
  3750 		if ( $this->current_post + 1 < $this->post_count ) {
  3126 			return true;
  3751 			return true;
  3127 		} elseif ( $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) {
  3752 		} elseif ( $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) {
  3128 			do_action_ref_array('loop_end', array(&$this));
  3753 			/**
       
  3754 			 * Fires once the loop has ended.
       
  3755 			 *
       
  3756 			 * @since 2.0.0
       
  3757 			 *
       
  3758 			 * @param WP_Query &$this The WP_Query instance (passed by reference).
       
  3759 			 */
       
  3760 			do_action_ref_array( 'loop_end', array( &$this ) );
  3129 			// Do some cleaning up after the loop
  3761 			// Do some cleaning up after the loop
  3130 			$this->rewind_posts();
  3762 			$this->rewind_posts();
  3131 		}
  3763 		}
  3132 
  3764 
  3133 		$this->in_the_loop = false;
  3765 		$this->in_the_loop = false;
  3138 	 * Rewind the posts and reset post index.
  3770 	 * Rewind the posts and reset post index.
  3139 	 *
  3771 	 *
  3140 	 * @since 1.5.0
  3772 	 * @since 1.5.0
  3141 	 * @access public
  3773 	 * @access public
  3142 	 */
  3774 	 */
  3143 	function rewind_posts() {
  3775 	public function rewind_posts() {
  3144 		$this->current_post = -1;
  3776 		$this->current_post = -1;
  3145 		if ( $this->post_count > 0 ) {
  3777 		if ( $this->post_count > 0 ) {
  3146 			$this->post = $this->posts[0];
  3778 			$this->post = $this->posts[0];
  3147 		}
  3779 		}
  3148 	}
  3780 	}
  3153 	 * @since 2.2.0
  3785 	 * @since 2.2.0
  3154 	 * @access public
  3786 	 * @access public
  3155 	 *
  3787 	 *
  3156 	 * @return object Comment object.
  3788 	 * @return object Comment object.
  3157 	 */
  3789 	 */
  3158 	function next_comment() {
  3790 	public function next_comment() {
  3159 		$this->current_comment++;
  3791 		$this->current_comment++;
  3160 
  3792 
  3161 		$this->comment = $this->comments[$this->current_comment];
  3793 		$this->comment = $this->comments[$this->current_comment];
  3162 		return $this->comment;
  3794 		return $this->comment;
  3163 	}
  3795 	}
  3166 	 * Sets up the current comment.
  3798 	 * Sets up the current comment.
  3167 	 *
  3799 	 *
  3168 	 * @since 2.2.0
  3800 	 * @since 2.2.0
  3169 	 * @access public
  3801 	 * @access public
  3170 	 * @global object $comment Current comment.
  3802 	 * @global object $comment Current comment.
  3171 	 * @uses do_action() Calls 'comment_loop_start' hook when first comment is processed.
  3803 	 */
  3172 	 */
  3804 	public function the_comment() {
  3173 	function the_comment() {
       
  3174 		global $comment;
  3805 		global $comment;
  3175 
  3806 
  3176 		$comment = $this->next_comment();
  3807 		$comment = $this->next_comment();
  3177 
  3808 
  3178 		if ( $this->current_comment == 0 ) {
  3809 		if ( $this->current_comment == 0 ) {
  3179 			do_action('comment_loop_start');
  3810 			/**
       
  3811 			 * Fires once the comment loop is started.
       
  3812 			 *
       
  3813 			 * @since 2.2.0
       
  3814 			 */
       
  3815 			do_action( 'comment_loop_start' );
  3180 		}
  3816 		}
  3181 	}
  3817 	}
  3182 
  3818 
  3183 	/**
  3819 	/**
  3184 	 * Whether there are more comments available.
  3820 	 * Whether there are more comments available.
  3188 	 * @since 2.2.0
  3824 	 * @since 2.2.0
  3189 	 * @access public
  3825 	 * @access public
  3190 	 *
  3826 	 *
  3191 	 * @return bool True, if more comments. False, if no more posts.
  3827 	 * @return bool True, if more comments. False, if no more posts.
  3192 	 */
  3828 	 */
  3193 	function have_comments() {
  3829 	public function have_comments() {
  3194 		if ( $this->current_comment + 1 < $this->comment_count ) {
  3830 		if ( $this->current_comment + 1 < $this->comment_count ) {
  3195 			return true;
  3831 			return true;
  3196 		} elseif ( $this->current_comment + 1 == $this->comment_count ) {
  3832 		} elseif ( $this->current_comment + 1 == $this->comment_count ) {
  3197 			$this->rewind_comments();
  3833 			$this->rewind_comments();
  3198 		}
  3834 		}
  3204 	 * Rewind the comments, resets the comment index and comment to first.
  3840 	 * Rewind the comments, resets the comment index and comment to first.
  3205 	 *
  3841 	 *
  3206 	 * @since 2.2.0
  3842 	 * @since 2.2.0
  3207 	 * @access public
  3843 	 * @access public
  3208 	 */
  3844 	 */
  3209 	function rewind_comments() {
  3845 	public function rewind_comments() {
  3210 		$this->current_comment = -1;
  3846 		$this->current_comment = -1;
  3211 		if ( $this->comment_count > 0 ) {
  3847 		if ( $this->comment_count > 0 ) {
  3212 			$this->comment = $this->comments[0];
  3848 			$this->comment = $this->comments[0];
  3213 		}
  3849 		}
  3214 	}
  3850 	}
  3220 	 * @access public
  3856 	 * @access public
  3221 	 *
  3857 	 *
  3222 	 * @param string $query URL query string.
  3858 	 * @param string $query URL query string.
  3223 	 * @return array List of posts.
  3859 	 * @return array List of posts.
  3224 	 */
  3860 	 */
  3225 	function query( $query ) {
  3861 	public function query( $query ) {
  3226 		$this->init();
  3862 		$this->init();
  3227 		$this->query = $this->query_vars = wp_parse_args( $query );
  3863 		$this->query = $this->query_vars = wp_parse_args( $query );
  3228 		return $this->get_posts();
  3864 		return $this->get_posts();
  3229 	}
  3865 	}
  3230 
  3866 
  3238 	 * @since 1.5.0
  3874 	 * @since 1.5.0
  3239 	 * @access public
  3875 	 * @access public
  3240 	 *
  3876 	 *
  3241 	 * @return object
  3877 	 * @return object
  3242 	 */
  3878 	 */
  3243 	function get_queried_object() {
  3879 	public function get_queried_object() {
  3244 		if ( isset($this->queried_object) )
  3880 		if ( isset($this->queried_object) )
  3245 			return $this->queried_object;
  3881 			return $this->queried_object;
  3246 
  3882 
  3247 		$this->queried_object = null;
  3883 		$this->queried_object = null;
  3248 		$this->queried_object_id = 0;
  3884 		$this->queried_object_id = 0;
  3249 
  3885 
  3250 		if ( $this->is_category || $this->is_tag || $this->is_tax ) {
  3886 		if ( $this->is_category || $this->is_tag || $this->is_tax ) {
  3251 			$tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' );
  3887 			if ( $this->is_category ) {
  3252 
  3888 				if ( $this->get( 'cat' ) ) {
  3253 			$query = reset( $tax_query_in_and );
  3889 					$term = get_term( $this->get( 'cat' ), 'category' );
  3254 
  3890 				} elseif ( $this->get( 'category_name' ) ) {
  3255 			if ( 'term_id' == $query['field'] )
  3891 					$term = get_term_by( 'slug', $this->get( 'category_name' ), 'category' );
  3256 				$term = get_term( reset( $query['terms'] ), $query['taxonomy'] );
  3892 				}
  3257 			elseif ( $query['terms'] )
  3893 			} elseif ( $this->is_tag ) {
  3258 				$term = get_term_by( $query['field'], reset( $query['terms'] ), $query['taxonomy'] );
  3894 				if ( $this->get( 'tag_id' ) ) {
       
  3895 					$term = get_term( $this->get( 'tag_id' ), 'post_tag' );
       
  3896 				} elseif ( $this->get( 'tag' ) ) {
       
  3897 					$term = get_term_by( 'slug', $this->get( 'tag' ), 'post_tag' );
       
  3898 				}
       
  3899 			} else {
       
  3900 				// For other tax queries, grab the first term from the first clause.
       
  3901 				$tax_query_in_and = wp_list_filter( $this->tax_query->queried_terms, array( 'operator' => 'NOT IN' ), 'NOT' );
       
  3902 
       
  3903 				if ( ! empty( $tax_query_in_and ) ) {
       
  3904 					$queried_taxonomies = array_keys( $tax_query_in_and );
       
  3905 					$matched_taxonomy = reset( $queried_taxonomies );
       
  3906 					$query = $tax_query_in_and[ $matched_taxonomy ];
       
  3907 
       
  3908 					if ( $query['terms'] ) {
       
  3909 						if ( 'term_id' == $query['field'] ) {
       
  3910 							$term = get_term( reset( $query['terms'] ), $matched_taxonomy );
       
  3911 						} else {
       
  3912 							$term = get_term_by( $query['field'], reset( $query['terms'] ), $matched_taxonomy );
       
  3913 						}
       
  3914 					}
       
  3915 				}
       
  3916 			}
  3259 
  3917 
  3260 			if ( ! empty( $term ) && ! is_wp_error( $term ) )  {
  3918 			if ( ! empty( $term ) && ! is_wp_error( $term ) )  {
  3261 				$this->queried_object = $term;
  3919 				$this->queried_object = $term;
  3262 				$this->queried_object_id = (int) $term->term_id;
  3920 				$this->queried_object_id = (int) $term->term_id;
  3263 
  3921 
  3264 				if ( $this->is_category )
  3922 				if ( $this->is_category && 'category' === $this->queried_object->taxonomy )
  3265 					_make_cat_compat( $this->queried_object );
  3923 					_make_cat_compat( $this->queried_object );
  3266 			}
  3924 			}
  3267 		} elseif ( $this->is_post_type_archive ) {
  3925 		} elseif ( $this->is_post_type_archive ) {
  3268 			$post_type = $this->get( 'post_type' );
  3926 			$post_type = $this->get( 'post_type' );
  3269 			if ( is_array( $post_type ) )
  3927 			if ( is_array( $post_type ) )
  3271 			$this->queried_object = get_post_type_object( $post_type );
  3929 			$this->queried_object = get_post_type_object( $post_type );
  3272 		} elseif ( $this->is_posts_page ) {
  3930 		} elseif ( $this->is_posts_page ) {
  3273 			$page_for_posts = get_option('page_for_posts');
  3931 			$page_for_posts = get_option('page_for_posts');
  3274 			$this->queried_object = get_post( $page_for_posts );
  3932 			$this->queried_object = get_post( $page_for_posts );
  3275 			$this->queried_object_id = (int) $this->queried_object->ID;
  3933 			$this->queried_object_id = (int) $this->queried_object->ID;
  3276 		} elseif ( $this->is_singular && !is_null($this->post) ) {
  3934 		} elseif ( $this->is_singular && ! empty( $this->post ) ) {
  3277 			$this->queried_object = $this->post;
  3935 			$this->queried_object = $this->post;
  3278 			$this->queried_object_id = (int) $this->post->ID;
  3936 			$this->queried_object_id = (int) $this->post->ID;
  3279 		} elseif ( $this->is_author ) {
  3937 		} elseif ( $this->is_author ) {
  3280 			$this->queried_object_id = (int) $this->get('author');
  3938 			$this->queried_object_id = (int) $this->get('author');
  3281 			$this->queried_object = get_userdata( $this->queried_object_id );
  3939 			$this->queried_object = get_userdata( $this->queried_object_id );
  3290 	 * @since 1.5.0
  3948 	 * @since 1.5.0
  3291 	 * @access public
  3949 	 * @access public
  3292 	 *
  3950 	 *
  3293 	 * @return int
  3951 	 * @return int
  3294 	 */
  3952 	 */
  3295 	function get_queried_object_id() {
  3953 	public function get_queried_object_id() {
  3296 		$this->get_queried_object();
  3954 		$this->get_queried_object();
  3297 
  3955 
  3298 		if ( isset($this->queried_object_id) ) {
  3956 		if ( isset($this->queried_object_id) ) {
  3299 			return $this->queried_object_id;
  3957 			return $this->queried_object_id;
  3300 		}
  3958 		}
  3308 	 * Sets up the WordPress query, if parameter is not empty.
  3966 	 * Sets up the WordPress query, if parameter is not empty.
  3309 	 *
  3967 	 *
  3310 	 * @since 1.5.0
  3968 	 * @since 1.5.0
  3311 	 * @access public
  3969 	 * @access public
  3312 	 *
  3970 	 *
  3313 	 * @param string $query URL query string.
  3971 	 * @param string|array $query URL query string or array of vars.
  3314 	 * @return WP_Query
  3972 	 */
  3315 	 */
  3973 	public function __construct($query = '') {
  3316 	function __construct($query = '') {
       
  3317 		if ( ! empty($query) ) {
  3974 		if ( ! empty($query) ) {
  3318 			$this->query($query);
  3975 			$this->query($query);
  3319 		}
  3976 		}
       
  3977 	}
       
  3978 
       
  3979 	/**
       
  3980 	 * Make private properties readable for backwards compatibility.
       
  3981 	 *
       
  3982 	 * @since 4.0.0
       
  3983 	 * @access public
       
  3984 	 *
       
  3985 	 * @param string $name Property to get.
       
  3986 	 * @return mixed Property.
       
  3987 	 */
       
  3988 	public function __get( $name ) {
       
  3989 		if ( in_array( $name, $this->compat_fields ) ) {
       
  3990 			return $this->$name;
       
  3991 		}
       
  3992 	}
       
  3993 
       
  3994 	/**
       
  3995 	 * Make private properties checkable for backwards compatibility.
       
  3996 	 *
       
  3997 	 * @since 4.0.0
       
  3998 	 * @access public
       
  3999 	 *
       
  4000 	 * @param string $name Property to check if set.
       
  4001 	 * @return bool Whether the property is set.
       
  4002 	 */
       
  4003 	public function __isset( $name ) {
       
  4004 		if ( in_array( $name, $this->compat_fields ) ) {
       
  4005 			return isset( $this->$name );
       
  4006 		}
       
  4007 	}
       
  4008 
       
  4009 	/**
       
  4010 	 * Make private/protected methods readable for backwards compatibility.
       
  4011 	 *
       
  4012 	 * @since 4.0.0
       
  4013 	 * @access public
       
  4014 	 *
       
  4015 	 * @param callable $name      Method to call.
       
  4016 	 * @param array    $arguments Arguments to pass when calling.
       
  4017 	 * @return mixed|bool Return value of the callback, false otherwise.
       
  4018 	 */
       
  4019 	public function __call( $name, $arguments ) {
       
  4020 		if ( in_array( $name, $this->compat_methods ) ) {
       
  4021 			return call_user_func_array( array( $this, $name ), $arguments );
       
  4022 		}
       
  4023 		return false;
  3320 	}
  4024 	}
  3321 
  4025 
  3322 	/**
  4026 	/**
  3323  	 * Is the query for an existing archive page?
  4027  	 * Is the query for an existing archive page?
  3324  	 *
  4028  	 *
  3326 	 *
  4030 	 *
  3327  	 * @since 3.1.0
  4031  	 * @since 3.1.0
  3328  	 *
  4032  	 *
  3329  	 * @return bool
  4033  	 * @return bool
  3330  	 */
  4034  	 */
  3331 	function is_archive() {
  4035 	public function is_archive() {
  3332 		return (bool) $this->is_archive;
  4036 		return (bool) $this->is_archive;
  3333 	}
  4037 	}
  3334 
  4038 
  3335 	/**
  4039 	/**
  3336 	 * Is the query for an existing post type archive page?
  4040 	 * Is the query for an existing post type archive page?
  3338 	 * @since 3.1.0
  4042 	 * @since 3.1.0
  3339 	 *
  4043 	 *
  3340 	 * @param mixed $post_types Optional. Post type or array of posts types to check against.
  4044 	 * @param mixed $post_types Optional. Post type or array of posts types to check against.
  3341 	 * @return bool
  4045 	 * @return bool
  3342 	 */
  4046 	 */
  3343 	function is_post_type_archive( $post_types = '' ) {
  4047 	public function is_post_type_archive( $post_types = '' ) {
  3344 		if ( empty( $post_types ) || ! $this->is_post_type_archive )
  4048 		if ( empty( $post_types ) || ! $this->is_post_type_archive )
  3345 			return (bool) $this->is_post_type_archive;
  4049 			return (bool) $this->is_post_type_archive;
  3346 
  4050 
  3347 		$post_type = $this->get( 'post_type' );
  4051 		$post_type = $this->get( 'post_type' );
  3348 		if ( is_array( $post_type ) )
  4052 		if ( is_array( $post_type ) )
  3355 	/**
  4059 	/**
  3356 	 * Is the query for an existing attachment page?
  4060 	 * Is the query for an existing attachment page?
  3357 	 *
  4061 	 *
  3358 	 * @since 3.1.0
  4062 	 * @since 3.1.0
  3359 	 *
  4063 	 *
       
  4064 	 * @param mixed $attachment Attachment ID, title, slug, or array of such.
  3360 	 * @return bool
  4065 	 * @return bool
  3361 	 */
  4066 	 */
  3362 	function is_attachment() {
  4067 	public function is_attachment( $attachment = '' ) {
  3363 		return (bool) $this->is_attachment;
  4068 		if ( ! $this->is_attachment ) {
       
  4069 			return false;
       
  4070 		}
       
  4071 
       
  4072 		if ( empty( $attachment ) ) {
       
  4073 			return true;
       
  4074 		}
       
  4075 
       
  4076 		$attachment = (array) $attachment;
       
  4077 
       
  4078 		$post_obj = $this->get_queried_object();
       
  4079 
       
  4080 		if ( in_array( (string) $post_obj->ID, $attachment ) ) {
       
  4081 			return true;
       
  4082 		} elseif ( in_array( $post_obj->post_title, $attachment ) ) {
       
  4083 			return true;
       
  4084 		} elseif ( in_array( $post_obj->post_name, $attachment ) ) {
       
  4085 			return true;
       
  4086 		}
       
  4087 		return false;
  3364 	}
  4088 	}
  3365 
  4089 
  3366 	/**
  4090 	/**
  3367 	 * Is the query for an existing author archive page?
  4091 	 * Is the query for an existing author archive page?
  3368 	 *
  4092 	 *
  3372 	 * @since 3.1.0
  4096 	 * @since 3.1.0
  3373 	 *
  4097 	 *
  3374 	 * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
  4098 	 * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
  3375 	 * @return bool
  4099 	 * @return bool
  3376 	 */
  4100 	 */
  3377 	function is_author( $author = '' ) {
  4101 	public function is_author( $author = '' ) {
  3378 		if ( !$this->is_author )
  4102 		if ( !$this->is_author )
  3379 			return false;
  4103 			return false;
  3380 
  4104 
  3381 		if ( empty($author) )
  4105 		if ( empty($author) )
  3382 			return true;
  4106 			return true;
  3383 
  4107 
  3384 		$author_obj = $this->get_queried_object();
  4108 		$author_obj = $this->get_queried_object();
  3385 
  4109 
  3386 		$author = (array) $author;
  4110 		$author = (array) $author;
  3387 
  4111 
  3388 		if ( in_array( $author_obj->ID, $author ) )
  4112 		if ( in_array( (string) $author_obj->ID, $author ) )
  3389 			return true;
  4113 			return true;
  3390 		elseif ( in_array( $author_obj->nickname, $author ) )
  4114 		elseif ( in_array( $author_obj->nickname, $author ) )
  3391 			return true;
  4115 			return true;
  3392 		elseif ( in_array( $author_obj->user_nicename, $author ) )
  4116 		elseif ( in_array( $author_obj->user_nicename, $author ) )
  3393 			return true;
  4117 			return true;
  3404 	 * @since 3.1.0
  4128 	 * @since 3.1.0
  3405 	 *
  4129 	 *
  3406 	 * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
  4130 	 * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
  3407 	 * @return bool
  4131 	 * @return bool
  3408 	 */
  4132 	 */
  3409 	function is_category( $category = '' ) {
  4133 	public function is_category( $category = '' ) {
  3410 		if ( !$this->is_category )
  4134 		if ( !$this->is_category )
  3411 			return false;
  4135 			return false;
  3412 
  4136 
  3413 		if ( empty($category) )
  4137 		if ( empty($category) )
  3414 			return true;
  4138 			return true;
  3415 
  4139 
  3416 		$cat_obj = $this->get_queried_object();
  4140 		$cat_obj = $this->get_queried_object();
  3417 
  4141 
  3418 		$category = (array) $category;
  4142 		$category = (array) $category;
  3419 
  4143 
  3420 		if ( in_array( $cat_obj->term_id, $category ) )
  4144 		if ( in_array( (string) $cat_obj->term_id, $category ) )
  3421 			return true;
  4145 			return true;
  3422 		elseif ( in_array( $cat_obj->name, $category ) )
  4146 		elseif ( in_array( $cat_obj->name, $category ) )
  3423 			return true;
  4147 			return true;
  3424 		elseif ( in_array( $cat_obj->slug, $category ) )
  4148 		elseif ( in_array( $cat_obj->slug, $category ) )
  3425 			return true;
  4149 			return true;
  3436 	 * @since 3.1.0
  4160 	 * @since 3.1.0
  3437 	 *
  4161 	 *
  3438 	 * @param mixed $tag Optional. Tag ID, name, slug, or array of Tag IDs, names, and slugs.
  4162 	 * @param mixed $tag Optional. Tag ID, name, slug, or array of Tag IDs, names, and slugs.
  3439 	 * @return bool
  4163 	 * @return bool
  3440 	 */
  4164 	 */
  3441 	function is_tag( $tag = '' ) {
  4165 	public function is_tag( $tag = '' ) {
  3442 		if ( ! $this->is_tag )
  4166 		if ( ! $this->is_tag )
  3443 			return false;
  4167 			return false;
  3444 
  4168 
  3445 		if ( empty( $tag ) )
  4169 		if ( empty( $tag ) )
  3446 			return true;
  4170 			return true;
  3447 
  4171 
  3448 		$tag_obj = $this->get_queried_object();
  4172 		$tag_obj = $this->get_queried_object();
  3449 
  4173 
  3450 		$tag = (array) $tag;
  4174 		$tag = (array) $tag;
  3451 
  4175 
  3452 		if ( in_array( $tag_obj->term_id, $tag ) )
  4176 		if ( in_array( (string) $tag_obj->term_id, $tag ) )
  3453 			return true;
  4177 			return true;
  3454 		elseif ( in_array( $tag_obj->name, $tag ) )
  4178 		elseif ( in_array( $tag_obj->name, $tag ) )
  3455 			return true;
  4179 			return true;
  3456 		elseif ( in_array( $tag_obj->slug, $tag ) )
  4180 		elseif ( in_array( $tag_obj->slug, $tag ) )
  3457 			return true;
  4181 			return true;
  3470 	 * specified.
  4194 	 * specified.
  3471 	 *
  4195 	 *
  3472 	 * @since 3.1.0
  4196 	 * @since 3.1.0
  3473 	 *
  4197 	 *
  3474 	 * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
  4198 	 * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
  3475 	 * @param mixed $term. Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
  4199 	 * @param mixed $term     Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
  3476 	 * @return bool
  4200 	 * @return bool
  3477 	 */
  4201 	 */
  3478 	function is_tax( $taxonomy = '', $term = '' ) {
  4202 	public function is_tax( $taxonomy = '', $term = '' ) {
  3479 		global $wp_taxonomies;
  4203 		global $wp_taxonomies;
  3480 
  4204 
  3481 		if ( !$this->is_tax )
  4205 		if ( !$this->is_tax )
  3482 			return false;
  4206 			return false;
  3483 
  4207 
  3508 	 *
  4232 	 *
  3509 	 * @since 3.1.0
  4233 	 * @since 3.1.0
  3510 	 *
  4234 	 *
  3511 	 * @return bool
  4235 	 * @return bool
  3512 	 */
  4236 	 */
  3513 	function is_comments_popup() {
  4237 	public function is_comments_popup() {
  3514 		return (bool) $this->is_comments_popup;
  4238 		return (bool) $this->is_comments_popup;
  3515 	}
  4239 	}
  3516 
  4240 
  3517 	/**
  4241 	/**
  3518 	 * Is the query for an existing date archive?
  4242 	 * Is the query for an existing date archive?
  3519 	 *
  4243 	 *
  3520 	 * @since 3.1.0
  4244 	 * @since 3.1.0
  3521 	 *
  4245 	 *
  3522 	 * @return bool
  4246 	 * @return bool
  3523 	 */
  4247 	 */
  3524 	function is_date() {
  4248 	public function is_date() {
  3525 		return (bool) $this->is_date;
  4249 		return (bool) $this->is_date;
  3526 	}
  4250 	}
  3527 
  4251 
  3528 	/**
  4252 	/**
  3529 	 * Is the query for an existing day archive?
  4253 	 * Is the query for an existing day archive?
  3530 	 *
  4254 	 *
  3531 	 * @since 3.1.0
  4255 	 * @since 3.1.0
  3532 	 *
  4256 	 *
  3533 	 * @return bool
  4257 	 * @return bool
  3534 	 */
  4258 	 */
  3535 	function is_day() {
  4259 	public function is_day() {
  3536 		return (bool) $this->is_day;
  4260 		return (bool) $this->is_day;
  3537 	}
  4261 	}
  3538 
  4262 
  3539 	/**
  4263 	/**
  3540 	 * Is the query for a feed?
  4264 	 * Is the query for a feed?
  3542 	 * @since 3.1.0
  4266 	 * @since 3.1.0
  3543 	 *
  4267 	 *
  3544 	 * @param string|array $feeds Optional feed types to check.
  4268 	 * @param string|array $feeds Optional feed types to check.
  3545 	 * @return bool
  4269 	 * @return bool
  3546 	 */
  4270 	 */
  3547 	function is_feed( $feeds = '' ) {
  4271 	public function is_feed( $feeds = '' ) {
  3548 		if ( empty( $feeds ) || ! $this->is_feed )
  4272 		if ( empty( $feeds ) || ! $this->is_feed )
  3549 			return (bool) $this->is_feed;
  4273 			return (bool) $this->is_feed;
  3550 		$qv = $this->get( 'feed' );
  4274 		$qv = $this->get( 'feed' );
  3551 		if ( 'feed' == $qv )
  4275 		if ( 'feed' == $qv )
  3552 			$qv = get_default_feed();
  4276 			$qv = get_default_feed();
  3558 	 *
  4282 	 *
  3559 	 * @since 3.1.0
  4283 	 * @since 3.1.0
  3560 	 *
  4284 	 *
  3561 	 * @return bool
  4285 	 * @return bool
  3562 	 */
  4286 	 */
  3563 	function is_comment_feed() {
  4287 	public function is_comment_feed() {
  3564 		return (bool) $this->is_comment_feed;
  4288 		return (bool) $this->is_comment_feed;
  3565 	}
  4289 	}
  3566 
  4290 
  3567 	/**
  4291 	/**
  3568 	 * Is the query for the front page of the site?
  4292 	 * Is the query for the front page of the site?
  3575 	 * true when viewing that page.
  4299 	 * true when viewing that page.
  3576 	 *
  4300 	 *
  3577 	 * Otherwise the same as @see WP_Query::is_home()
  4301 	 * Otherwise the same as @see WP_Query::is_home()
  3578 	 *
  4302 	 *
  3579 	 * @since 3.1.0
  4303 	 * @since 3.1.0
  3580 	 * @uses is_home()
       
  3581 	 * @uses get_option()
       
  3582 	 *
  4304 	 *
  3583 	 * @return bool True, if front of site.
  4305 	 * @return bool True, if front of site.
  3584 	 */
  4306 	 */
  3585 	function is_front_page() {
  4307 	public function is_front_page() {
  3586 		// most likely case
  4308 		// most likely case
  3587 		if ( 'posts' == get_option( 'show_on_front') && $this->is_home() )
  4309 		if ( 'posts' == get_option( 'show_on_front') && $this->is_home() )
  3588 			return true;
  4310 			return true;
  3589 		elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) )
  4311 		elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) )
  3590 			return true;
  4312 			return true;
  3606 	 *
  4328 	 *
  3607 	 * @since 3.1.0
  4329 	 * @since 3.1.0
  3608 	 *
  4330 	 *
  3609 	 * @return bool True if blog view homepage.
  4331 	 * @return bool True if blog view homepage.
  3610 	 */
  4332 	 */
  3611 	function is_home() {
  4333 	public function is_home() {
  3612 		return (bool) $this->is_home;
  4334 		return (bool) $this->is_home;
  3613 	}
  4335 	}
  3614 
  4336 
  3615 	/**
  4337 	/**
  3616 	 * Is the query for an existing month archive?
  4338 	 * Is the query for an existing month archive?
  3617 	 *
  4339 	 *
  3618 	 * @since 3.1.0
  4340 	 * @since 3.1.0
  3619 	 *
  4341 	 *
  3620 	 * @return bool
  4342 	 * @return bool
  3621 	 */
  4343 	 */
  3622 	function is_month() {
  4344 	public function is_month() {
  3623 		return (bool) $this->is_month;
  4345 		return (bool) $this->is_month;
  3624 	}
  4346 	}
  3625 
  4347 
  3626 	/**
  4348 	/**
  3627 	 * Is the query for an existing single page?
  4349 	 * Is the query for an existing single page?
  3632 	 * @see WP_Query::is_single()
  4354 	 * @see WP_Query::is_single()
  3633 	 * @see WP_Query::is_singular()
  4355 	 * @see WP_Query::is_singular()
  3634 	 *
  4356 	 *
  3635 	 * @since 3.1.0
  4357 	 * @since 3.1.0
  3636 	 *
  4358 	 *
  3637 	 * @param mixed $page Page ID, title, slug, or array of such.
  4359 	 * @param mixed $page Page ID, title, slug, path, or array of such.
  3638 	 * @return bool
  4360 	 * @return bool
  3639 	 */
  4361 	 */
  3640 	function is_page( $page = '' ) {
  4362 	public function is_page( $page = '' ) {
  3641 		if ( !$this->is_page )
  4363 		if ( !$this->is_page )
  3642 			return false;
  4364 			return false;
  3643 
  4365 
  3644 		if ( empty( $page ) )
  4366 		if ( empty( $page ) )
  3645 			return true;
  4367 			return true;
  3646 
  4368 
  3647 		$page_obj = $this->get_queried_object();
  4369 		$page_obj = $this->get_queried_object();
  3648 
  4370 
  3649 		$page = (array) $page;
  4371 		$page = (array) $page;
  3650 
  4372 
  3651 		if ( in_array( $page_obj->ID, $page ) )
  4373 		if ( in_array( (string) $page_obj->ID, $page ) ) {
  3652 			return true;
  4374 			return true;
  3653 		elseif ( in_array( $page_obj->post_title, $page ) )
  4375 		} elseif ( in_array( $page_obj->post_title, $page ) ) {
  3654 			return true;
  4376 			return true;
  3655 		else if ( in_array( $page_obj->post_name, $page ) )
  4377 		} elseif ( in_array( $page_obj->post_name, $page ) ) {
  3656 			return true;
  4378 			return true;
       
  4379 		} else {
       
  4380 			foreach ( $page as $pagepath ) {
       
  4381 				if ( ! strpos( $pagepath, '/' ) ) {
       
  4382 					continue;
       
  4383 				}
       
  4384 				$pagepath_obj = get_page_by_path( $pagepath );
       
  4385 
       
  4386 				if ( $pagepath_obj && ( $pagepath_obj->ID == $page_obj->ID ) ) {
       
  4387 					return true;
       
  4388 				}
       
  4389 			}
       
  4390 		}
  3657 
  4391 
  3658 		return false;
  4392 		return false;
  3659 	}
  4393 	}
  3660 
  4394 
  3661 	/**
  4395 	/**
  3663 	 *
  4397 	 *
  3664 	 * @since 3.1.0
  4398 	 * @since 3.1.0
  3665 	 *
  4399 	 *
  3666 	 * @return bool
  4400 	 * @return bool
  3667 	 */
  4401 	 */
  3668 	function is_paged() {
  4402 	public function is_paged() {
  3669 		return (bool) $this->is_paged;
  4403 		return (bool) $this->is_paged;
  3670 	}
  4404 	}
  3671 
  4405 
  3672 	/**
  4406 	/**
  3673 	 * Is the query for a post or page preview?
  4407 	 * Is the query for a post or page preview?
  3674 	 *
  4408 	 *
  3675 	 * @since 3.1.0
  4409 	 * @since 3.1.0
  3676 	 *
  4410 	 *
  3677 	 * @return bool
  4411 	 * @return bool
  3678 	 */
  4412 	 */
  3679 	function is_preview() {
  4413 	public function is_preview() {
  3680 		return (bool) $this->is_preview;
  4414 		return (bool) $this->is_preview;
  3681 	}
  4415 	}
  3682 
  4416 
  3683 	/**
  4417 	/**
  3684 	 * Is the query for the robots file?
  4418 	 * Is the query for the robots file?
  3685 	 *
  4419 	 *
  3686 	 * @since 3.1.0
  4420 	 * @since 3.1.0
  3687 	 *
  4421 	 *
  3688 	 * @return bool
  4422 	 * @return bool
  3689 	 */
  4423 	 */
  3690 	function is_robots() {
  4424 	public function is_robots() {
  3691 		return (bool) $this->is_robots;
  4425 		return (bool) $this->is_robots;
  3692 	}
  4426 	}
  3693 
  4427 
  3694 	/**
  4428 	/**
  3695 	 * Is the query for a search?
  4429 	 * Is the query for a search?
  3696 	 *
  4430 	 *
  3697 	 * @since 3.1.0
  4431 	 * @since 3.1.0
  3698 	 *
  4432 	 *
  3699 	 * @return bool
  4433 	 * @return bool
  3700 	 */
  4434 	 */
  3701 	function is_search() {
  4435 	public function is_search() {
  3702 		return (bool) $this->is_search;
  4436 		return (bool) $this->is_search;
  3703 	}
  4437 	}
  3704 
  4438 
  3705 	/**
  4439 	/**
  3706 	 * Is the query for an existing single post?
  4440 	 * Is the query for an existing single post?
  3713 	 * @see WP_Query::is_page()
  4447 	 * @see WP_Query::is_page()
  3714 	 * @see WP_Query::is_singular()
  4448 	 * @see WP_Query::is_singular()
  3715 	 *
  4449 	 *
  3716 	 * @since 3.1.0
  4450 	 * @since 3.1.0
  3717 	 *
  4451 	 *
  3718 	 * @param mixed $post Post ID, title, slug, or array of such.
  4452 	 * @param mixed $post Post ID, title, slug, path, or array of such.
  3719 	 * @return bool
  4453 	 * @return bool
  3720 	 */
  4454 	 */
  3721 	function is_single( $post = '' ) {
  4455 	public function is_single( $post = '' ) {
  3722 		if ( !$this->is_single )
  4456 		if ( !$this->is_single )
  3723 			return false;
  4457 			return false;
  3724 
  4458 
  3725 		if ( empty($post) )
  4459 		if ( empty($post) )
  3726 			return true;
  4460 			return true;
  3727 
  4461 
  3728 		$post_obj = $this->get_queried_object();
  4462 		$post_obj = $this->get_queried_object();
  3729 
  4463 
  3730 		$post = (array) $post;
  4464 		$post = (array) $post;
  3731 
  4465 
  3732 		if ( in_array( $post_obj->ID, $post ) )
  4466 		if ( in_array( (string) $post_obj->ID, $post ) ) {
  3733 			return true;
  4467 			return true;
  3734 		elseif ( in_array( $post_obj->post_title, $post ) )
  4468 		} elseif ( in_array( $post_obj->post_title, $post ) ) {
  3735 			return true;
  4469 			return true;
  3736 		elseif ( in_array( $post_obj->post_name, $post ) )
  4470 		} elseif ( in_array( $post_obj->post_name, $post ) ) {
  3737 			return true;
  4471 			return true;
  3738 
  4472 		} else {
       
  4473 			foreach ( $post as $postpath ) {
       
  4474 				if ( ! strpos( $postpath, '/' ) ) {
       
  4475 					continue;
       
  4476 				}
       
  4477 				$postpath_obj = get_page_by_path( $postpath, OBJECT, $post_obj->post_type );
       
  4478 
       
  4479 				if ( $postpath_obj && ( $postpath_obj->ID == $post_obj->ID ) ) {
       
  4480 					return true;
       
  4481 				}
       
  4482 			}
       
  4483 		}
  3739 		return false;
  4484 		return false;
  3740 	}
  4485 	}
  3741 
  4486 
  3742 	/**
  4487 	/**
  3743 	 * Is the query for an existing single post of any post type (post, attachment, page, ... )?
  4488 	 * Is the query for an existing single post of any post type (post, attachment, page, ... )?
  3751 	 * @since 3.1.0
  4496 	 * @since 3.1.0
  3752 	 *
  4497 	 *
  3753 	 * @param mixed $post_types Optional. Post Type or array of Post Types
  4498 	 * @param mixed $post_types Optional. Post Type or array of Post Types
  3754 	 * @return bool
  4499 	 * @return bool
  3755 	 */
  4500 	 */
  3756 	function is_singular( $post_types = '' ) {
  4501 	public function is_singular( $post_types = '' ) {
  3757 		if ( empty( $post_types ) || !$this->is_singular )
  4502 		if ( empty( $post_types ) || !$this->is_singular )
  3758 			return (bool) $this->is_singular;
  4503 			return (bool) $this->is_singular;
  3759 
  4504 
  3760 		$post_obj = $this->get_queried_object();
  4505 		$post_obj = $this->get_queried_object();
  3761 
  4506 
  3767 	 *
  4512 	 *
  3768 	 * @since 3.1.0
  4513 	 * @since 3.1.0
  3769 	 *
  4514 	 *
  3770 	 * @return bool
  4515 	 * @return bool
  3771 	 */
  4516 	 */
  3772 	function is_time() {
  4517 	public function is_time() {
  3773 		return (bool) $this->is_time;
  4518 		return (bool) $this->is_time;
  3774 	}
  4519 	}
  3775 
  4520 
  3776 	/**
  4521 	/**
  3777 	 * Is the query for a trackback endpoint call?
  4522 	 * Is the query for a trackback endpoint call?
  3778 	 *
  4523 	 *
  3779 	 * @since 3.1.0
  4524 	 * @since 3.1.0
  3780 	 *
  4525 	 *
  3781 	 * @return bool
  4526 	 * @return bool
  3782 	 */
  4527 	 */
  3783 	function is_trackback() {
  4528 	public function is_trackback() {
  3784 		return (bool) $this->is_trackback;
  4529 		return (bool) $this->is_trackback;
  3785 	}
  4530 	}
  3786 
  4531 
  3787 	/**
  4532 	/**
  3788 	 * Is the query for an existing year archive?
  4533 	 * Is the query for an existing year archive?
  3789 	 *
  4534 	 *
  3790 	 * @since 3.1.0
  4535 	 * @since 3.1.0
  3791 	 *
  4536 	 *
  3792 	 * @return bool
  4537 	 * @return bool
  3793 	 */
  4538 	 */
  3794 	function is_year() {
  4539 	public function is_year() {
  3795 		return (bool) $this->is_year;
  4540 		return (bool) $this->is_year;
  3796 	}
  4541 	}
  3797 
  4542 
  3798 	/**
  4543 	/**
  3799 	 * Is the query a 404 (returns no results)?
  4544 	 * Is the query a 404 (returns no results)?
  3800 	 *
  4545 	 *
  3801 	 * @since 3.1.0
  4546 	 * @since 3.1.0
  3802 	 *
  4547 	 *
  3803 	 * @return bool
  4548 	 * @return bool
  3804 	 */
  4549 	 */
  3805 	function is_404() {
  4550 	public function is_404() {
  3806 		return (bool) $this->is_404;
  4551 		return (bool) $this->is_404;
  3807 	}
  4552 	}
  3808 
  4553 
  3809 	/**
  4554 	/**
  3810 	 * Is the query the main query?
  4555 	 * Is the query the main query?
  3811 	 *
  4556 	 *
  3812 	 * @since 3.3.0
  4557 	 * @since 3.3.0
  3813 	 *
  4558 	 *
  3814 	 * @return bool
  4559 	 * @return bool
  3815 	 */
  4560 	 */
  3816 	function is_main_query() {
  4561 	public function is_main_query() {
  3817 		global $wp_the_query;
  4562 		global $wp_the_query;
  3818 		return $wp_the_query === $this;
  4563 		return $wp_the_query === $this;
  3819 	}
  4564 	}
  3820 
  4565 
  3821 	/**
  4566 	/**
       
  4567 	 * Set up global post data.
       
  4568 	 *
       
  4569 	 * @since 4.1.0
       
  4570 	 *
       
  4571 	 * @param WP_Post $post Post data.
       
  4572 	 * @return bool True when finished.
       
  4573 	 */
       
  4574 	public function setup_postdata( $post ) {
       
  4575 		global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages;
       
  4576 
       
  4577 		$id = (int) $post->ID;
       
  4578 
       
  4579 		$authordata = get_userdata($post->post_author);
       
  4580 
       
  4581 		$currentday = mysql2date('d.m.y', $post->post_date, false);
       
  4582 		$currentmonth = mysql2date('m', $post->post_date, false);
       
  4583 		$numpages = 1;
       
  4584 		$multipage = 0;
       
  4585 		$page = $this->get( 'page' );
       
  4586 		if ( ! $page )
       
  4587 			$page = 1;
       
  4588 
       
  4589 		/*
       
  4590 		 * Force full post content when viewing the permalink for the $post,
       
  4591 		 * or when on an RSS feed. Otherwise respect the 'more' tag.
       
  4592 		 */
       
  4593 		if ( $post->ID === get_queried_object_id() && ( $this->is_page() || $this->is_single() ) ) {
       
  4594 			$more = 1;
       
  4595 		} elseif ( $this->is_feed() ) {
       
  4596 			$more = 1;
       
  4597 		} else {
       
  4598 			$more = 0;
       
  4599 		}
       
  4600 
       
  4601 		$content = $post->post_content;
       
  4602 		if ( false !== strpos( $content, '<!--nextpage-->' ) ) {
       
  4603 			if ( $page > 1 )
       
  4604 				$more = 1;
       
  4605 			$content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content );
       
  4606 			$content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content );
       
  4607 			$content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content );
       
  4608 
       
  4609 			// Ignore nextpage at the beginning of the content.
       
  4610 			if ( 0 === strpos( $content, '<!--nextpage-->' ) )
       
  4611 				$content = substr( $content, 15 );
       
  4612 
       
  4613 			$pages = explode('<!--nextpage-->', $content);
       
  4614 			$numpages = count($pages);
       
  4615 			if ( $numpages > 1 )
       
  4616 				$multipage = 1;
       
  4617 		} else {
       
  4618 			$pages = array( $post->post_content );
       
  4619 		}
       
  4620 
       
  4621 		/**
       
  4622 		 * Fires once the post data has been setup.
       
  4623 		 *
       
  4624 		 * @since 2.8.0
       
  4625 		 * @since 4.1.0 Introduced `$this` parameter.
       
  4626 		 *
       
  4627 		 * @param WP_Post  &$post The Post object (passed by reference).
       
  4628 		 * @param WP_Query &$this The current Query object (passed by reference).
       
  4629 		 */
       
  4630 		do_action_ref_array( 'the_post', array( &$post, &$this ) );
       
  4631 
       
  4632 		return true;
       
  4633 	}
       
  4634 	/**
  3822 	 * After looping through a nested query, this function
  4635 	 * After looping through a nested query, this function
  3823 	 * restores the $post global to the current post in this query.
  4636 	 * restores the $post global to the current post in this query.
  3824 	 *
  4637 	 *
  3825 	 * @since 3.7.0
  4638 	 * @since 3.7.0
  3826 	 *
  4639 	 */
  3827 	 * @return bool
  4640 	public function reset_postdata() {
  3828 	 */
       
  3829 	function reset_postdata() {
       
  3830 		if ( ! empty( $this->post ) ) {
  4641 		if ( ! empty( $this->post ) ) {
  3831 			$GLOBALS['post'] = $this->post;
  4642 			$GLOBALS['post'] = $this->post;
  3832 			setup_postdata( $this->post );
  4643 			setup_postdata( $this->post );
  3833 		}
  4644 		}
  3834 	}
  4645 	}
  3838  * Redirect old slugs to the correct permalink.
  4649  * Redirect old slugs to the correct permalink.
  3839  *
  4650  *
  3840  * Attempts to find the current slug from the past slugs.
  4651  * Attempts to find the current slug from the past slugs.
  3841  *
  4652  *
  3842  * @since 2.1.0
  4653  * @since 2.1.0
       
  4654  *
  3843  * @uses $wp_query
  4655  * @uses $wp_query
  3844  * @uses $wpdb
  4656  * @global wpdb $wpdb WordPress database abstraction object.
  3845  *
  4657  *
  3846  * @return null If no link is found, null is returned.
  4658  * @return null If no link is found, null is returned.
  3847  */
  4659  */
  3848 function wp_old_slug_redirect() {
  4660 function wp_old_slug_redirect() {
  3849 	global $wp_query;
  4661 	global $wp_query;
  3859 			$post_type = 'post';
  4671 			$post_type = 'post';
  3860 
  4672 
  3861 		if ( is_array( $post_type ) ) {
  4673 		if ( is_array( $post_type ) ) {
  3862 			if ( count( $post_type ) > 1 )
  4674 			if ( count( $post_type ) > 1 )
  3863 				return;
  4675 				return;
  3864 			$post_type = array_shift( $post_type );
  4676 			$post_type = reset( $post_type );
  3865 		}
  4677 		}
  3866 
  4678 
  3867 		// Do not attempt redirect for hierarchical post types
  4679 		// Do not attempt redirect for hierarchical post types
  3868 		if ( is_post_type_hierarchical( $post_type ) )
  4680 		if ( is_post_type_hierarchical( $post_type ) )
  3869 			return;
  4681 			return;
  3898  * Set up global post data.
  4710  * Set up global post data.
  3899  *
  4711  *
  3900  * @since 1.5.0
  4712  * @since 1.5.0
  3901  *
  4713  *
  3902  * @param object $post Post data.
  4714  * @param object $post Post data.
  3903  * @uses do_action_ref_array() Calls 'the_post'
       
  3904  * @return bool True when finished.
  4715  * @return bool True when finished.
  3905  */
  4716  */
  3906 function setup_postdata( $post ) {
  4717 function setup_postdata( $post ) {
  3907 	global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages;
  4718 	global $wp_query;
  3908 
  4719 
  3909 	$id = (int) $post->ID;
  4720 	if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) {
  3910 
  4721 		return $wp_query->setup_postdata( $post );
  3911 	$authordata = get_userdata($post->post_author);
  4722 	}
  3912 
  4723 
  3913 	$currentday = mysql2date('d.m.y', $post->post_date, false);
  4724 	return false;
  3914 	$currentmonth = mysql2date('m', $post->post_date, false);
       
  3915 	$numpages = 1;
       
  3916 	$multipage = 0;
       
  3917 	$page = get_query_var('page');
       
  3918 	if ( ! $page )
       
  3919 		$page = 1;
       
  3920 	if ( is_single() || is_page() || is_feed() )
       
  3921 		$more = 1;
       
  3922 	$content = $post->post_content;
       
  3923 	if ( false !== strpos( $content, '<!--nextpage-->' ) ) {
       
  3924 		if ( $page > 1 )
       
  3925 			$more = 1;
       
  3926 		$content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content );
       
  3927 		$content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content );
       
  3928 		$content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content );
       
  3929 		// Ignore nextpage at the beginning of the content.
       
  3930 		if ( 0 === strpos( $content, '<!--nextpage-->' ) )
       
  3931 			$content = substr( $content, 15 );
       
  3932 		$pages = explode('<!--nextpage-->', $content);
       
  3933 		$numpages = count($pages);
       
  3934 		if ( $numpages > 1 )
       
  3935 			$multipage = 1;
       
  3936 	} else {
       
  3937 		$pages = array( $post->post_content );
       
  3938 	}
       
  3939 
       
  3940 	do_action_ref_array('the_post', array(&$post));
       
  3941 
       
  3942 	return true;
       
  3943 }
  4725 }