| [ Index ] |
PHP Cross Reference of Wordpress 2.7.1 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WordPress Query API 4 * 5 * The query API attempts to get which part of WordPress to the user is on. It 6 * also provides functionality to getting URL query information. 7 * 8 * @link http://codex.wordpress.org/The_Loop More information on The Loop. 9 * 10 * @package WordPress 11 * @subpackage Query 12 */ 13 14 /** 15 * Retrieve variable in the WP_Query class. 16 * 17 * @see WP_Query::get() 18 * @since 1.5.0 19 * @uses $wp_query 20 * 21 * @param string $var The variable key to retrieve. 22 * @return mixed 23 */ 24 function get_query_var($var) { 25 global $wp_query; 26 27 return $wp_query->get($var); 28 } 29 30 /** 31 * Set query variable. 32 * 33 * @see WP_Query::set() 34 * @since 2.2.0 35 * @uses $wp_query 36 * 37 * @param string $var Query variable key. 38 * @param mixed $value 39 * @return null 40 */ 41 function set_query_var($var, $value) { 42 global $wp_query; 43 44 return $wp_query->set($var, $value); 45 } 46 47 /** 48 * Setup The Loop with query parameters. 49 * 50 * This will override the current WordPress Loop and shouldn't be used more than 51 * once. This must not be used within the WordPress Loop. 52 * 53 * @since 1.5.0 54 * @uses $wp_query 55 * 56 * @param string $query 57 * @return array List of posts 58 */ 59 function &query_posts($query) { 60 unset($GLOBALS['wp_query']); 61 $GLOBALS['wp_query'] =& new WP_Query(); 62 return $GLOBALS['wp_query']->query($query); 63 } 64 65 /** 66 * Destroy the previous query and setup a new query. 67 * 68 * This should be used after {@link query_posts()} and before another {@link 69 * query_posts()}. This will remove obscure bugs that occur when the previous 70 * wp_query object is not destroyed properly before another is setup. 71 * 72 * @since 2.3.0 73 * @uses $wp_query 74 */ 75 function wp_reset_query() { 76 unset($GLOBALS['wp_query']); 77 $GLOBALS['wp_query'] =& $GLOBALS['wp_the_query']; 78 global $wp_query; 79 if ( !empty($wp_query->post) ) { 80 $GLOBALS['post'] = $wp_query->post; 81 setup_postdata($wp_query->post); 82 } 83 } 84 85 /* 86 * Query type checks. 87 */ 88 89 /** 90 * Whether the current request is in WordPress admin Panel 91 * 92 * Does not inform on whether the user is an admin! Use capability checks to 93 * tell if the user should be accessing a section or not. 94 * 95 * @since 1.5.1 96 * 97 * @return bool True if inside WordPress administration pages. 98 */ 99 function is_admin () { 100 if ( defined('WP_ADMIN') ) 101 return WP_ADMIN; 102 return false; 103 } 104 105 /** 106 * Is query requesting an archive page. 107 * 108 * @since 1.5.0 109 * @uses $wp_query 110 * 111 * @return bool True if page is archive. 112 */ 113 function is_archive () { 114 global $wp_query; 115 116 return $wp_query->is_archive; 117 } 118 119 /** 120 * Is query requesting an attachment page. 121 * 122 * @since 2.0.0 123 * @uses $wp_query 124 * 125 * @return bool True if page is attachment. 126 */ 127 function is_attachment () { 128 global $wp_query; 129 130 return $wp_query->is_attachment; 131 } 132 133 /** 134 * Is query requesting an author page. 135 * 136 * If the $author parameter is specified then the check will be expanded to 137 * include whether the queried author matches the one given in the parameter. 138 * You can match against integers and against strings. 139 * 140 * If matching against an integer, the ID should be used of the author for the 141 * test. If the $author is an ID and matches the author page user ID, then 142 * 'true' will be returned. 143 * 144 * If matching against strings, then the test will be matched against both the 145 * nickname and user nicename and will return true on success. 146 * 147 * @since 1.5.0 148 * @uses $wp_query 149 * 150 * @param string|int $author Optional. Is current page this author. 151 * @return bool True if page is author or $author (if set). 152 */ 153 function is_author ($author = '') { 154 global $wp_query; 155 156 if ( !$wp_query->is_author ) 157 return false; 158 159 if ( empty($author) ) 160 return true; 161 162 $author_obj = $wp_query->get_queried_object(); 163 164 $author = (array) $author; 165 166 if ( in_array( $author_obj->ID, $author ) ) 167 return true; 168 elseif ( in_array( $author_obj->nickname, $author ) ) 169 return true; 170 elseif ( in_array( $author_obj->user_nicename, $author ) ) 171 return true; 172 173 return false; 174 } 175 176 /** 177 * Whether current page query contains a category name or given category name. 178 * 179 * The category list can contain category IDs, names, or category slugs. If any 180 * of them are part of the query, then it will return true. 181 * 182 * @since 1.5.0 183 * @uses $wp_query 184 * 185 * @param string|array $category Optional. 186 * @return bool 187 */ 188 function is_category ($category = '') { 189 global $wp_query; 190 191 if ( !$wp_query->is_category ) 192 return false; 193 194 if ( empty($category) ) 195 return true; 196 197 $cat_obj = $wp_query->get_queried_object(); 198 199 $category = (array) $category; 200 201 if ( in_array( $cat_obj->term_id, $category ) ) 202 return true; 203 elseif ( in_array( $cat_obj->name, $category ) ) 204 return true; 205 elseif ( in_array( $cat_obj->slug, $category ) ) 206 return true; 207 208 return false; 209 } 210 211 /** 212 * Whether the current page query has the given tag slug or contains tag. 213 * 214 * @since 2.3.0 215 * @uses $wp_query 216 * 217 * @param string|array $slug Optional. Single tag or list of tags to check for. 218 * @return bool 219 */ 220 function is_tag( $slug = '' ) { 221 global $wp_query; 222 223 if ( !$wp_query->is_tag ) 224 return false; 225 226 if ( empty( $slug ) ) 227 return true; 228 229 $tag_obj = $wp_query->get_queried_object(); 230 231 $slug = (array) $slug; 232 233 if ( in_array( $tag_obj->slug, $slug ) ) 234 return true; 235 236 return false; 237 } 238 239 /** 240 * Whether the current page query has the given taxonomy slug or contains taxonomy. 241 * 242 * @since 2.5.0 243 * @uses $wp_query 244 * 245 * @param string|array $slug Optional. Slug or slugs to check in current query. 246 * @return bool 247 */ 248 function is_tax( $slug = '' ) { 249 global $wp_query; 250 251 if ( !$wp_query->is_tax ) 252 return false; 253 254 if ( empty($slug) ) 255 return true; 256 257 $term = $wp_query->get_queried_object(); 258 259 $slug = (array) $slug; 260 261 if ( in_array( $term->slug, $slug ) ) 262 return true; 263 264 return false; 265 } 266 267 /** 268 * Whether the current URL is within the comments popup window. 269 * 270 * @since 1.5.0 271 * @uses $wp_query 272 * 273 * @return bool 274 */ 275 function is_comments_popup () { 276 global $wp_query; 277 278 return $wp_query->is_comments_popup; 279 } 280 281 /** 282 * Whether current URL is based on a date. 283 * 284 * @since 1.5.0 285 * @uses $wp_query 286 * 287 * @return bool 288 */ 289 function is_date () { 290 global $wp_query; 291 292 return $wp_query->is_date; 293 } 294 295 /** 296 * Whether current blog URL contains a day. 297 * 298 * @since 1.5.0 299 * @uses $wp_query 300 * 301 * @return bool 302 */ 303 function is_day () { 304 global $wp_query; 305 306 return $wp_query->is_day; 307 } 308 309 /** 310 * Whether current page query is feed URL. 311 * 312 * @since 1.5.0 313 * @uses $wp_query 314 * 315 * @return bool 316 */ 317 function is_feed () { 318 global $wp_query; 319 320 return $wp_query->is_feed; 321 } 322 323 /** 324 * Whether current page query is the front of the site. 325 * 326 * @since 2.5.0 327 * @uses is_home() 328 * @uses get_option() 329 * 330 * @return bool True, if front of site. 331 */ 332 function is_front_page () { 333 // most likely case 334 if ( 'posts' == get_option('show_on_front') && is_home() ) 335 return true; 336 elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') && is_page(get_option('page_on_front')) ) 337 return true; 338 else 339 return false; 340 } 341 342 /** 343 * Whether current page view is the blog homepage. 344 * 345 * @since 1.5.0 346 * @uses $wp_query 347 * 348 * @return bool True if blog view homepage. 349 */ 350 function is_home () { 351 global $wp_query; 352 353 return $wp_query->is_home; 354 } 355 356 /** 357 * Whether current page query contains a month. 358 * 359 * @since 1.5.0 360 * @uses $wp_query 361 * 362 * @return bool 363 */ 364 function is_month () { 365 global $wp_query; 366 367 return $wp_query->is_month; 368 } 369 370 /** 371 * Whether query is page or contains given page(s). 372 * 373 * Calls the function without any parameters will only test whether the current 374 * query is of the page type. Either a list or a single item can be tested 375 * against for whether the query is a page and also is the value or one of the 376 * values in the page parameter. 377 * 378 * The parameter can contain the page ID, page title, or page name. The 379 * parameter can also be an array of those three values. 380 * 381 * @since 1.5.0 382 * @uses $wp_query 383 * 384 * @param mixed $page Either page or list of pages to test against. 385 * @return bool 386 */ 387 function is_page ($page = '') { 388 global $wp_query; 389 390 if ( !$wp_query->is_page ) 391 return false; 392 393 if ( empty($page) ) 394 return true; 395 396 $page_obj = $wp_query->get_queried_object(); 397 398 $page = (array) $page; 399 400 if ( in_array( $page_obj->ID, $page ) ) 401 return true; 402 elseif ( in_array( $page_obj->post_title, $page ) ) 403 return true; 404 else if ( in_array( $page_obj->post_name, $page ) ) 405 return true; 406 407 return false; 408 } 409 410 /** 411 * Whether query contains multiple pages for the results. 412 * 413 * @since 1.5.0 414 * @uses $wp_query 415 * 416 * @return bool 417 */ 418 function is_paged () { 419 global $wp_query; 420 421 return $wp_query->is_paged; 422 } 423 424 /** 425 * Whether the current page was created by a plugin. 426 * 427 * The plugin can set this by using the global $plugin_page and setting it to 428 * true. 429 * 430 * @since 1.5.0 431 * @global bool $plugin_page Used by plugins to tell the query that current is a plugin page. 432 * 433 * @return bool 434 */ 435 function is_plugin_page() { 436 global $plugin_page; 437 438 if ( isset($plugin_page) ) 439 return true; 440 441 return false; 442 } 443 444 /** 445 * Whether the current query is preview of post or page. 446 * 447 * @since 2.0.0 448 * @uses $wp_query 449 * 450 * @return bool 451 */ 452 function is_preview() { 453 global $wp_query; 454 455 return $wp_query->is_preview; 456 } 457 458 /** 459 * Whether the current query post is robots. 460 * 461 * @since 2.1.0 462 * @uses $wp_query 463 * 464 * @return bool 465 */ 466 function is_robots() { 467 global $wp_query; 468 469 return $wp_query->is_robots; 470 } 471 472 /** 473 * Whether current query is the result of a user search. 474 * 475 * @since 1.5.0 476 * @uses $wp_query 477 * 478 * @return bool 479 */ 480 function is_search () { 481 global $wp_query; 482 483 return $wp_query->is_search; 484 } 485 486 /** 487 * Whether the current page query is single page. 488 * 489 * The parameter can contain the post ID, post title, or post name. The 490 * parameter can also be an array of those three values. 491 * 492 * This applies to other post types, attachments, pages, posts. Just means that 493 * the current query has only a single object. 494 * 495 * @since 1.5.0 496 * @uses $wp_query 497 * 498 * @param mixed $post Either post or list of posts to test against. 499 * @return bool 500 */ 501 function is_single ($post = '') { 502 global $wp_query; 503 504 if ( !$wp_query->is_single ) 505 return false; 506 507 if ( empty( $post) ) 508 return true; 509 510 $post_obj = $wp_query->get_queried_object(); 511 512 $post = (array) $post; 513 514 if ( in_array( $post_obj->ID, $post ) ) 515 return true; 516 elseif ( in_array( $post_obj->post_title, $post ) ) 517 return true; 518 elseif ( in_array( $post_obj->post_name, $post ) ) 519 return true; 520 521 return false; 522 } 523 524 /** 525 * Whether is single post, is a page, or is an attachment. 526 * 527 * @since 1.5.0 528 * @uses $wp_query 529 * 530 * @return bool 531 */ 532 function is_singular() { 533 global $wp_query; 534 535 return $wp_query->is_singular; 536 } 537 538 /** 539 * Whether the query contains a time. 540 * 541 * @since 1.5.0 542 * @uses $wp_query 543 * 544 * @return bool 545 */ 546 function is_time () { 547 global $wp_query; 548 549 return $wp_query->is_time; 550 } 551 552 /** 553 * Whether the query is a trackback. 554 * 555 * @since 1.5.0 556 * @uses $wp_query 557 * 558 * @return bool 559 */ 560 function is_trackback () { 561 global $wp_query; 562 563 return $wp_query->is_trackback; 564 } 565 566 /** 567 * Whether the query contains a year. 568 * 569 * @since 1.5.0 570 * @uses $wp_query 571 * 572 * @return bool 573 */ 574 function is_year () { 575 global $wp_query; 576 577 return $wp_query->is_year; 578 } 579 580 /** 581 * Whether current page query is a 404 and no results for WordPress query. 582 * 583 * @since 1.5.0 584 * @uses $wp_query 585 * 586 * @return bool True, if nothing is found matching WordPress Query. 587 */ 588 function is_404 () { 589 global $wp_query; 590 591 return $wp_query->is_404; 592 } 593 594 /* 595 * The Loop. Post loop control. 596 */ 597 598 /** 599 * Whether current WordPress query has results to loop over. 600 * 601 * @see WP_Query::have_posts() 602 * @since 1.5.0 603 * @uses $wp_query 604 * 605 * @return bool 606 */ 607 function have_posts() { 608 global $wp_query; 609 610 return $wp_query->have_posts(); 611 } 612 613 /** 614 * Whether the caller is in the Loop. 615 * 616 * @since 2.0.0 617 * @uses $wp_query 618 * 619 * @return bool True if caller is within loop, false if loop hasn't started or ended. 620 */ 621 function in_the_loop() { 622 global $wp_query; 623 624 return $wp_query->in_the_loop; 625 } 626 627 /** 628 * Rewind the loop posts. 629 * 630 * @see WP_Query::rewind_posts() 631 * @since 1.5.0 632 * @uses $wp_query 633 * 634 * @return null 635 */ 636 function rewind_posts() { 637 global $wp_query; 638 639 return $wp_query->rewind_posts(); 640 } 641 642 /** 643 * Iterate the post index in the loop. 644 * 645 * @see WP_Query::the_post() 646 * @since 1.5.0 647 * @uses $wp_query 648 */ 649 function the_post() { 650 global $wp_query; 651 652 $wp_query->the_post(); 653 } 654 655 /* 656 * Comments loop. 657 */ 658 659 /** 660 * Whether there are comments to loop over. 661 * 662 * @see WP_Query::have_comments() 663 * @since 2.2.0 664 * @uses $wp_query 665 * 666 * @return bool 667 */ 668 function have_comments() { 669 global $wp_query; 670 return $wp_query->have_comments(); 671 } 672 673 /** 674 * Iterate comment index in the comment loop. 675 * 676 * @see WP_Query::the_comment() 677 * @since 2.2.0 678 * @uses $wp_query 679 * 680 * @return object 681 */ 682 function the_comment() { 683 global $wp_query; 684 return $wp_query->the_comment(); 685 } 686 687 /* 688 * WP_Query 689 */ 690 691 /** 692 * The WordPress Query class. 693 * 694 * @link http://codex.wordpress.org/Function_Reference/WP_Query Codex page. 695 * 696 * @since 1.5.0 697 */ 698 class WP_Query { 699 700 /** 701 * Query string 702 * 703 * @since 1.5.0 704 * @access public 705 * @var string 706 */ 707 var $query; 708 709 /** 710 * Query search variables set by the user. 711 * 712 * @since 1.5.0 713 * @access public 714 * @var array 715 */ 716 var $query_vars = array(); 717 718 /** 719 * Holds the data for a single object that is queried. 720 * 721 * Holds the contents of a post, page, category, attachment. 722 * 723 * @since 1.5.0 724 * @access public 725 * @var object|array 726 */ 727 var $queried_object; 728 729 /** 730 * The ID of the queried object. 731 * 732 * @since 1.5.0 733 * @access public 734 * @var int 735 */ 736 var $queried_object_id; 737 738 /** 739 * Get post database query. 740 * 741 * @since 2.0.1 742 * @access public 743 * @var string 744 */ 745 var $request; 746 747 /** 748 * List of posts. 749 * 750 * @since 1.5.0 751 * @access public 752 * @var array 753 */ 754 var $posts; 755 756 /** 757 * The amount of posts for the current query. 758 * 759 * @since 1.5.0 760 * @access public 761 * @var int 762 */ 763 var $post_count = 0; 764 765 /** 766 * Index of the current item in the loop. 767 * 768 * @since 1.5.0 769 * @access public 770 * @var int 771 */ 772 var $current_post = -1; 773 774 /** 775 * Whether the loop has started and the caller is in the loop. 776 * 777 * @since 2.0.0 778 * @access public 779 * @var bool 780 */ 781 var $in_the_loop = false; 782 783 /** 784 * The current post ID. 785 * 786 * @since 1.5.0 787 * @access public 788 * @var int 789 */ 790 var $post; 791 792 /** 793 * The list of comments for current post. 794 * 795 * @since 2.2.0 796 * @access public 797 * @var array 798 */ 799 var $comments; 800 801 /** 802 * The amount of comments for the posts. 803 * 804 * @since 2.2.0 805 * @access public 806 * @var int 807 */ 808 var $comment_count = 0; 809 810 /** 811 * The index of the comment in the comment loop. 812 * 813 * @since 2.2.0 814 * @access public 815 * @var int 816 */ 817 var $current_comment = -1; 818 819 /** 820 * Current comment ID. 821 * 822 * @since 2.2.0 823 * @access public 824 * @var int 825 */ 826 var $comment; 827 828 /** 829 * Amount of posts if limit clause was not used. 830 * 831 * @since 2.1.0 832 * @access public 833 * @var int 834 */ 835 var $found_posts = 0; 836 837 /** 838 * The amount of pages. 839 * 840 * @since 2.1.0 841 * @access public 842 * @var int 843 */ 844 var $max_num_pages = 0; 845 846 /** 847 * The amount of comment pages. 848 * 849 * @since 2.7.0 850 * @access public 851 * @var int 852 */ 853 var $max_num_comment_pages = 0; 854 855 /** 856 * Set if query is single post. 857 * 858 * @since 1.5.0 859 * @access public 860 * @var bool 861 */ 862 var $is_single = false; 863 864 /** 865 * Set if query is preview of blog. 866 * 867 * @since 2.0.0 868 * @access public 869 * @var bool 870 */ 871 var $is_preview = false; 872 873 /** 874 * Set if query returns a page. 875 * 876 * @since 1.5.0 877 * @access public 878 * @var bool 879 */ 880 var $is_page = false; 881 882 /** 883 * Set if query is an archive list. 884 * 885 * @since 1.5.0 886 * @access public 887 * @var bool 888 */ 889 var $is_archive = false; 890 891 /** 892 * Set if query is part of a date. 893 * 894 * @since 1.5.0 895 * @access public 896 * @var bool 897 */ 898 var $is_date = false; 899 900 /** 901 * Set if query contains a year. 902 * 903 * @since 1.5.0 904 * @access public 905 * @var bool 906 */ 907 var $is_year = false; 908 909 /** 910 * Set if query contains a month. 911 * 912 * @since 1.5.0 913 * @access public 914 * @var bool 915 */ 916 var $is_month = false; 917 918 /** 919 * Set if query contains a day. 920 * 921 * @since 1.5.0 922 * @access public 923 * @var bool 924 */ 925 var $is_day = false; 926 927 /** 928 * Set if query contains time. 929 * 930 * @since 1.5.0 931 * @access public 932 * @var bool 933 */ 934 var $is_time = false; 935 936 /** 937 * Set if query contains an author. 938 * 939 * @since 1.5.0 940 * @access public 941 * @var bool 942 */ 943 var $is_author = false; 944 945 /** 946 * Set if query contains category. 947 * 948 * @since 1.5.0 949 * @access public 950 * @var bool 951 */ 952 var $is_category = false; 953 954 /** 955 * Set if query contains tag. 956 * 957 * @since 2.3.0 958 * @access public 959 * @var bool 960 */ 961 var $is_tag = false; 962 963 /** 964 * Set if query contains taxonomy. 965 * 966 * @since 2.5.0 967 * @access public 968 * @var bool 969 */ 970 var $is_tax = false; 971 972 /** 973 * Set if query was part of a search result. 974 * 975 * @since 1.5.0 976 * @access public 977 * @var bool 978 */ 979 var $is_search = false; 980 981 /** 982 * Set if query is feed display. 983 * 984 * @since 1.5.0 985 * @access public 986 * @var bool 987 */ 988 var $is_feed = false; 989 990 /** 991 * Set if query is comment feed display. 992 * 993 * @since 2.2.0 994 * @access public 995 * @var bool 996 */ 997 var $is_comment_feed = false; 998 999 /** 1000 * Set if query is trackback. 1001 * 1002 * @since 1.5.0 1003 * @access public 1004 * @var bool 1005 */ 1006 var $is_trackback = false; 1007 1008 /** 1009 * Set if query is blog homepage. 1010 * 1011 * @since 1.5.0 1012 * @access public 1013 * @var bool 1014 */ 1015 var $is_home = false; 1016 1017 /** 1018 * Set if query couldn't found anything. 1019 * 1020 * @since 1.5.0 1021 * @access public 1022 * @var bool 1023 */ 1024 var $is_404 = false; 1025 1026 /** 1027 * Set if query is within comments popup window. 1028 * 1029 * @since 1.5.0 1030 * @access public 1031 * @var bool 1032 */ 1033 var $is_comments_popup = false; 1034 1035 /** 1036 * Set if query is part of administration page. 1037 * 1038 * @since 1.5.0 1039 * @access public 1040 * @var bool 1041 */ 1042 var $is_admin = false; 1043 1044 /** 1045 * Set if query is an attachment. 1046 * 1047 * @since 2.0.0 1048 * @access public 1049 * @var bool 1050 */ 1051 var $is_attachment = false; 1052 1053 /** 1054 * Set if is single, is a page, or is an attachment. 1055 * 1056 * @since 2.1.0 1057 * @access public 1058 * @var bool 1059 */ 1060 var $is_singular = false; 1061 1062 /** 1063 * Set if query is for robots. 1064 * 1065 * @since 2.1.0 1066 * @access public 1067 * @var bool 1068 */ 1069 var $is_robots = false; 1070 1071 /** 1072 * Set if query contains posts. 1073 * 1074 * Basically, the homepage if the option isn't set for the static homepage. 1075 * 1076 * @since 2.1.0 1077 * @access public 1078 * @var bool 1079 */ 1080 var $is_posts_page = false; 1081 1082 /** 1083 * Resets query flags to false. 1084 * 1085 * The query flags are what page info WordPress was able to figure out. 1086 * 1087 * @since 2.0.0 1088 * @access private 1089 */ 1090 function init_query_flags() { 1091 $this->is_single = false; 1092 $this->is_page = false; 1093 $this->is_archive = false; 1094 $this->is_date = false; 1095 $this->is_year = false; 1096 $this->is_month = false; 1097 $this->is_day = false; 1098 $this->is_time = false; 1099 $this->is_author = false; 1100 $this->is_category = false; 1101 $this->is_tag = false; 1102 $this->is_tax = false; 1103 $this->is_search = false; 1104 $this->is_feed = false; 1105 $this->is_comment_feed = false; 1106 $this->is_trackback = false; 1107 $this->is_home = false; 1108 $this->is_404 = false; 1109 $this->is_paged = false; 1110 $this->is_admin = false; 1111 $this->is_attachment = false; 1112 $this->is_singular = false; 1113 $this->is_robots = false; 1114 $this->is_posts_page = false; 1115 } 1116 1117 /** 1118 * Initiates object properties and sets default values. 1119 * 1120 * @since 1.5.0 1121 * @access public 1122 */ 1123 function init () { 1124 unset($this->posts); 1125 unset($this->query); 1126 $this->query_vars = array(); 1127 unset($this->queried_object); 1128 unset($this->queried_object_id); 1129 $this->post_count = 0; 1130 $this->current_post = -1; 1131 $this->in_the_loop = false; 1132 1133 $this->init_query_flags(); 1134 } 1135 1136 /** 1137 * Reparse the query vars. 1138 * 1139 * @since 1.5.0 1140 * @access public 1141 */ 1142 function parse_query_vars() { 1143 $this->parse_query(''); 1144 } 1145 1146 /** 1147 * Fills in the query variables, which do not exist within the parameter. 1148 * 1149 * @since 2.1.0 1150 * @access public 1151 * 1152 * @param array $array Defined query variables. 1153 * @return array Complete query variables with undefined ones filled in empty. 1154 */ 1155 function fill_query_vars($array) { 1156 $keys = array( 1157 'error' 1158 , 'm' 1159 , 'p' 1160 , 'post_parent' 1161 , 'subpost' 1162 , 'subpost_id' 1163 , 'attachment' 1164 , 'attachment_id' 1165 , 'name' 1166 , 'hour' 1167 , 'static' 1168 , 'pagename' 1169 , 'page_id' 1170 , 'second' 1171 , 'minute' 1172 , 'hour' 1173 , 'day' 1174 , 'monthnum' 1175 , 'year' 1176 , 'w' 1177 , 'category_name' 1178 , 'tag' 1179 , 'cat' 1180 , 'tag_id' 1181 , 'author_name' 1182 , 'feed' 1183 , 'tb' 1184 , 'paged' 1185 , 'comments_popup' 1186 , 'meta_key' 1187 , 'meta_value' 1188 , 'preview' 1189 ); 1190 1191 foreach ($keys as $key) { 1192 if ( !isset($array[$key])) 1193 $array[$key] = ''; 1194 } 1195 1196 $array_keys = array('category__in', 'category__not_in', 'category__and', 'post__in', 'post__not_in', 1197 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and'); 1198 1199 foreach ( $array_keys as $key ) { 1200 if ( !isset($array[$key])) 1201 $array[$key] = array(); 1202 } 1203 return $array; 1204 } 1205 1206 /** 1207 * Parse a query string and set query type booleans. 1208 * 1209 * @since 1.5.0 1210 * @access public 1211 * 1212 * @param string|array $query 1213 */ 1214 function parse_query ($query) { 1215 if ( !empty($query) || !isset($this->query) ) { 1216 $this->init(); 1217 if ( is_array($query) ) 1218 $this->query_vars = $query; 1219 else 1220 parse_str($query, $this->query_vars); 1221 $this->query = $query; 1222 } 1223 1224 $this->query_vars = $this->fill_query_vars($this->query_vars); 1225 $qv = &$this->query_vars; 1226 1227 if ( ! empty($qv['robots']) ) 1228 $this->is_robots = true; 1229 1230 $qv['p'] = absint($qv['p']); 1231 $qv['page_id'] = absint($qv['page_id']); 1232 $qv['year'] = absint($qv['year']); 1233 $qv['monthnum'] = absint($qv['monthnum']); 1234 $qv['day'] = absint($qv['day']); 1235 $qv['w'] = absint($qv['w']); 1236 $qv['m'] = absint($qv['m']); 1237 $qv['cat'] = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // comma separated list of positive or negative integers 1238 $qv['pagename'] = trim( $qv['pagename'] ); 1239 $qv['name'] = trim( $qv['name'] ); 1240 if ( '' !== $qv['hour'] ) $qv['hour'] = absint($qv['hour']); 1241 if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']); 1242 if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']); 1243 1244 // Compat. Map subpost to attachment. 1245 if ( '' != $qv['subpost'] ) 1246 $qv['attachment'] = $qv['subpost']; 1247 if ( '' != $qv['subpost_id'] ) 1248 $qv['attachment_id'] = $qv['subpost_id']; 1249 1250 $qv['attachment_id'] = absint($qv['attachment_id']); 1251 1252 if ( ('' != $qv['attachment']) || !empty($qv['attachment_id']) ) { 1253 $this->is_single = true; 1254 $this->is_attachment = true; 1255 } elseif ( '' != $qv['name'] ) { 1256 $this->is_single = true; 1257 } elseif ( $qv['p'] ) { 1258 $this->is_single = true; 1259 } elseif ( ('' !== $qv['hour']) && ('' !== $qv['minute']) &&('' !== $qv['second']) && ('' != $qv['year']) && ('' != $qv['monthnum']) && ('' != $qv['day']) ) { 1260 // If year, month, day, hour, minute, and second are set, a single 1261 // post is being queried. 1262 $this->is_single = true; 1263 } elseif ( '' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id']) ) { 1264 $this->is_page = true; 1265 $this->is_single = false; 1266 } elseif ( !empty($qv['s']) ) { 1267 $this->is_search = true; 1268 } else { 1269 // Look for archive queries. Dates, categories, authors. 1270 1271 if ( '' !== $qv['second'] ) { 1272 $this->is_time = true; 1273 $this->is_date = true; 1274 } 1275 1276 if ( '' !== $qv['minute'] ) { 1277 $this->is_time = true; 1278 $this->is_date = true; 1279 } 1280 1281 if ( '' !== $qv['hour'] ) { 1282 $this->is_time = true; 1283 $this->is_date = true; 1284 } 1285 1286 if ( $qv['day'] ) { 1287 if (! $this->is_date) { 1288 $this->is_day = true; 1289 $this->is_date = true; 1290 } 1291 } 1292 1293 if ( $qv['monthnum'] ) { 1294 if (! $this->is_date) { 1295 $this->is_month = true; 1296 $this->is_date = true; 1297 } 1298 } 1299 1300 if ( $qv['year'] ) { 1301 if (! $this->is_date) { 1302 $this->is_year = true; 1303 $this->is_date = true; 1304 } 1305 } 1306 1307 if ( $qv['m'] ) { 1308 $this->is_date = true; 1309 if (strlen($qv['m']) > 9) { 1310 $this->is_time = true; 1311 } else if (strlen($qv['m']) > 7) { 1312 $this->is_day = true; 1313 } else if (strlen($qv['m']) > 5) { 1314 $this->is_month = true; 1315 } else { 1316 $this->is_year = true; 1317 } 1318 } 1319 1320 if ('' != $qv['w']) { 1321 $this->is_date = true; 1322 } 1323 1324 if ( empty($qv['cat']) || ($qv['cat'] == '0') ) { 1325 $this->is_category = false; 1326 } else { 1327 if (strpos($qv['cat'], '-') !== false) { 1328 $this->is_category = false; 1329 } else { 1330 $this->is_category = true; 1331 } 1332 } 1333 1334 if ( '' != $qv['category_name'] ) { 1335 $this->is_category = true; 1336 } 1337 1338 if ( !is_array($qv['category__in']) || empty($qv['category__in']) ) { 1339 $qv['category__in'] = array(); 1340 } else { 1341 $qv['category__in'] = array_map('absint', $qv['category__in']); 1342 $this->is_category = true; 1343 } 1344 1345 if ( !is_array($qv['category__not_in']) || empty($qv['category__not_in']) ) { 1346 $qv['category__not_in'] = array(); 1347 } else { 1348 $qv['category__not_in'] = array_map('absint', $qv['category__not_in']); 1349 } 1350 1351 if ( !is_array($qv['category__and']) || empty($qv['category__and']) ) { 1352 $qv['category__and'] = array(); 1353 } else { 1354 $qv['category__and'] = array_map('absint', $qv['category__and']); 1355 $this->is_category = true; 1356 } 1357 1358 if ( '' != $qv['tag'] ) 1359 $this->is_tag = true; 1360 1361 $qv['tag_id'] = absint($qv['tag_id']); 1362 if ( !empty($qv['tag_id']) ) 1363 $this->is_tag = true; 1364 1365 if ( !is_array($qv['tag__in']) || empty($qv['tag__in']) ) { 1366 $qv['tag__in'] = array(); 1367 } else { 1368 $qv['tag__in'] = array_map('absint', $qv['tag__in']); 1369 $this->is_tag = true; 1370 } 1371 1372 if ( !is_array($qv['tag__not_in']) || empty($qv['tag__not_in']) ) { 1373 $qv['tag__not_in'] = array(); 1374 } else { 1375 $qv['tag__not_in'] = array_map('absint', $qv['tag__not_in']); 1376 } 1377 1378 if ( !is_array($qv['tag__and']) || empty($qv['tag__and']) ) { 1379 $qv['tag__and'] = array(); 1380 } else { 1381 $qv['tag__and'] = array_map('absint', $qv['tag__and']); 1382 $this->is_category = true; 1383 } 1384 1385 if ( !is_array($qv['tag_slug__in']) || empty($qv['tag_slug__in']) ) { 1386 $qv['tag_slug__in'] = array(); 1387 } else { 1388 $qv['tag_slug__in'] = array_map('sanitize_title', $qv['tag_slug__in']); 1389 $this->is_tag = true; 1390 } 1391 1392 if ( !is_array($qv['tag_slug__and']) || empty($qv['tag_slug__and']) ) { 1393 $qv['tag_slug__and'] = array(); 1394 } else { 1395 $qv['tag_slug__and'] = array_map('sanitize_title', $qv['tag_slug__and']); 1396 $this->is_tag = true; 1397 } 1398 1399 if ( empty($qv['taxonomy']) || empty($qv['term']) ) { 1400 $this->is_tax = false; 1401 foreach ( $GLOBALS['wp_taxonomies'] as $t ) { 1402 if ( isset($t->query_var) && isset($qv[$t->query_var]) && '' != $qv[$t->query_var] ) { 1403 $this->is_tax = true; 1404 break; 1405 } 1406 } 1407 } else { 1408 $this->is_tax = true; 1409 } 1410 1411 if ( empty($qv['author']) || ($qv['author'] == '0') ) { 1412 $this->is_author = false; 1413 } else { 1414 $this->is_author = true; 1415 } 1416 1417 if ( '' != $qv['author_name'] ) { 1418 $this->is_author = true; 1419 } 1420 1421 if ( ($this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax) ) 1422 $this->is_archive = true; 1423 } 1424 1425 if ( '' != $qv['feed'] ) 1426 $this->is_feed = true; 1427 1428 if ( '' != $qv['tb'] ) 1429 $this->is_trackback = true; 1430 1431 if ( '' != $qv['paged'] ) 1432 $this->is_paged = true; 1433 1434 if ( '' != $qv['comments_popup'] ) 1435 $this->is_comments_popup = true; 1436 1437 // if we're previewing inside the write screen 1438 if ('' != $qv['preview']) 1439 $this->is_preview = true; 1440 1441 if ( is_admin() ) 1442 $this->is_admin = true; 1443 1444 if ( false !== strpos($qv['feed'], 'comments-') ) { 1445 $qv['feed'] = str_replace('comments-', '', $qv['feed']); 1446 $qv['withcomments'] = 1; 1447 } 1448 1449 $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment; 1450 1451 if ( $this->is_feed && ( !empty($qv['withcomments']) || ( empty($qv['withoutcomments']) && $this->is_singular ) ) ) 1452 $this->is_comment_feed = true; 1453 1454 if ( !( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_comments_popup ) ) 1455 $this->is_home = true; 1456 1457 // Correct is_* for page_on_front and page_for_posts 1458 if ( $this->is_home && ( empty($this->query) || $qv['preview'] == 'true' ) && 'page' == get_option('show_on_front') && get_option('page_on_front') ) { 1459 $this->is_page = true; 1460 $this->is_home = false; 1461 $qv['page_id'] = get_option('page_on_front'); 1462 } 1463 1464 if ( '' != $qv['pagename'] ) { 1465 $this->queried_object =& get_page_by_path($qv['pagename']); 1466 if ( !empty($this->queried_object) ) 1467 $this->queried_object_id = (int) $this->queried_object->ID; 1468 else 1469 unset($this->queried_object); 1470 1471 if ( 'page' == get_option('show_on_front') && isset($this->queried_object_id) && $this->queried_object_id == get_option('page_for_posts') ) { 1472 $this->is_page = false; 1473 $this->is_home = true; 1474 $this->is_posts_page = true; 1475 } 1476 } 1477 1478 if ( $qv['page_id'] ) { 1479 if ( 'page' == get_option('show_on_front') && $qv['page_id'] == get_option('page_for_posts') ) { 1480 $this->is_page = false; 1481 $this->is_home = true; 1482 $this->is_posts_page = true; 1483 } 1484 } 1485 1486 if ( !empty($qv['post_type']) ) 1487 $qv['post_type'] = sanitize_user($qv['post_type'], true); 1488 1489 if ( !empty($qv['post_status']) ) 1490 $qv['post_status'] = preg_replace('|[^a-z0-9_,-]|', '', $qv['post_status']); 1491 1492 if ( $this->is_posts_page && ( ! isset($qv['withcomments']) || ! $qv['withcomments'] ) ) 1493 $this->is_comment_feed = false; 1494 1495 $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment; 1496 // Done correcting is_* for page_on_front and page_for_posts 1497 1498 if ('404' == $qv['error']) 1499 $this->set_404(); 1500 1501 if ( !empty($query) ) 1502 do_action_ref_array('parse_query', array(&$this)); 1503 } 1504 1505 /** 1506 * Sets the 404 property and saves whether query is feed. 1507 * 1508 * @since 2.0.0 1509 * @access public 1510 */ 1511 function set_404() { 1512 $is_feed = $this->is_feed; 1513 1514 $this->init_query_flags(); 1515 $this->is_404 = true; 1516 1517 $this->is_feed = $is_feed; 1518 } 1519 1520 /** 1521 * Retrieve query variable. 1522 * 1523 * @since 1.5.0 1524 * @access public 1525 * 1526 * @param string $query_var Query variable key. 1527 * @return mixed 1528 */ 1529 function get($query_var) { 1530 if (isset($this->query_vars[$query_var])) { 1531 return $this->query_vars[$query_var]; 1532 } 1533 1534 return ''; 1535 } 1536 1537 /** 1538 * Set query variable. 1539 * 1540 * @since 1.5.0 1541 * @access public 1542 * 1543 * @param string $query_var Query variable key. 1544 * @param mixed $value Query variable value. 1545 */ 1546 function set($query_var, $value) { 1547 $this->query_vars[$query_var] = $value; 1548 } 1549 1550 /** 1551 * Retrieve the posts based on query variables. 1552 * 1553 * There are a few filters and actions that can be used to modify the post 1554 * database query. 1555 * 1556 * @since 1.5.0 1557 * @access public 1558 * @uses do_action_ref_array() Calls 'pre_get_posts' hook before retrieving posts. 1559 * 1560 * @return array List of posts. 1561 */ 1562 function &get_posts() { 1563 global $wpdb, $user_ID; 1564 1565 do_action_ref_array('pre_get_posts', array(&$this)); 1566 1567 // Shorthand. 1568 $q = &$this->query_vars; 1569 1570 $q = $this->fill_query_vars($q); 1571 1572 // First let's clear some variables 1573 $distinct = ''; 1574 $whichcat = ''; 1575 $whichauthor = ''; 1576 $whichmimetype = ''; 1577 $where = ''; 1578 $limits = ''; 1579 $join = ''; 1580 $search = ''; 1581 $groupby = ''; 1582 $fields = "$wpdb->posts.*"; 1583 $post_status_join = false; 1584 $page = 1; 1585 1586 if ( !isset($q['caller_get_posts']) ) 1587 $q['caller_get_posts'] = false; 1588 1589 if ( !isset($q['suppress_filters']) ) 1590 $q['suppress_filters'] = false; 1591 1592 if ( !isset($q['post_type']) ) { 1593 if ( $this->is_search ) 1594 $q['post_type'] = 'any'; 1595 else 1596 $q['post_type'] = 'post'; 1597 } 1598 $post_type = $q['post_type']; 1599 if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 ) 1600 $q['posts_per_page'] = get_option('posts_per_page'); 1601 if ( isset($q['showposts']) && $q['showposts'] ) { 1602 $q['showposts'] = (int) $q['showposts']; 1603 $q['posts_per_page'] = $q['showposts']; 1604 } 1605 if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) ) 1606 $q['posts_per_page'] = $q['posts_per_archive_page']; 1607 if ( !isset($q['nopaging']) ) { 1608 if ($q['posts_per_page'] == -1) { 1609 $q['nopaging'] = true; 1610 } else { 1611 $q['nopaging'] = false; 1612 } 1613 } 1614 if ( $this->is_feed ) { 1615 $q['posts_per_page'] = get_option('posts_per_rss'); 1616 $q['nopaging'] = false; 1617 } 1618 $q['posts_per_page'] = (int) $q['posts_per_page']; 1619 if ( $q['posts_per_page'] < -1 ) 1620 $q['posts_per_page'] = abs($q['posts_per_page']); 1621 else if ( $q['posts_per_page'] == 0 ) 1622 $q['posts_per_page'] = 1; 1623 1624 if ( !isset($q['comments_per_page']) || $q['comments_per_page'] == 0 ) 1625 $q['comments_per_page'] = get_option('comments_per_page'); 1626 1627 if ( $this->is_home && (empty($this->query) || $q['preview'] == 'true') && ( 'page' == get_option('show_on_front') ) && get_option('page_on_front') ) { 1628 $this->is_page = true; 1629 $this->is_home = false; 1630 $q['page_id'] = get_option('page_on_front'); 1631 } 1632 1633 if (isset($q['page'])) { 1634 $q['page'] = trim($q['page'], '/'); 1635 $q['page'] = absint($q['page']); 1636 } 1637 1638 // If a month is specified in the querystring, load that month 1639 if ( $q['m'] ) { 1640 $q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']); 1641 $where .= " AND YEAR($wpdb->posts.post_date)=" . substr($q['m'], 0, 4); 1642 if (strlen($q['m'])>5) 1643 $where .= " AND MONTH($wpdb->posts.post_date)=" . substr($q['m'], 4, 2); 1644 if (strlen($q['m'])>7) 1645 $where .= " AND DAYOFMONTH($wpdb->posts.post_date)=" . substr($q['m'], 6, 2); 1646 if (strlen($q['m'])>9) 1647 $where .= " AND HOUR($wpdb->posts.post_date)=" . substr($q['m'], 8, 2); 1648 if (strlen($q['m'])>11) 1649 $where .= " AND MINUTE($wpdb->posts.post_date)=" . substr($q['m'], 10, 2); 1650 if (strlen($q['m'])>13) 1651 $where .= " AND SECOND($wpdb->posts.post_date)=" . substr($q['m'], 12, 2); 1652 } 1653 1654 if ( '' !== $q['hour'] ) 1655 $where .= " AND HOUR($wpdb->posts.post_date)='" . $q['hour'] . "'"; 1656 1657 if ( '' !== $q['minute'] ) 1658 $where .= " AND MINUTE($wpdb->posts.post_date)='" . $q['minute'] . "'"; 1659 1660 if ( '' !== $q['second'] ) 1661 $where .= " AND SECOND($wpdb->posts.post_date)='" . $q['second'] . "'"; 1662 1663 if ( $q['year'] ) 1664 $where .= " AND YEAR($wpdb->posts.post_date)='" . $q['year'] . "'"; 1665 1666 if ( $q['monthnum'] ) 1667 $where .= " AND MONTH($wpdb->posts.post_date)='" . $q['monthnum'] . "'"; 1668 1669 if ( $q['day'] ) 1670 $where .= " AND DAYOFMONTH($wpdb->posts.post_date)='" . $q['day'] . "'"; 1671 1672 if ('' != $q['name']) { 1673 $q['name'] = sanitize_title($q['name']); 1674 $where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'"; 1675 } else if ('' != $q['pagename']) { 1676 if ( isset($this->queried_object_id) ) 1677 $reqpage = $this->queried_object_id; 1678 else { 1679 $reqpage = get_page_by_path($q['pagename']); 1680 if ( !empty($reqpage) ) 1681 $reqpage = $reqpage->ID; 1682 else 1683 $reqpage = 0; 1684 } 1685 1686 $page_for_posts = get_option('page_for_posts'); 1687 if ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) { 1688 $q['pagename'] = str_replace('%2F', '/', urlencode(urldecode($q['pagename']))); 1689 $page_paths = '/' . trim($q['pagename'], '/'); 1690 $q['pagename'] = sanitize_title(basename($page_paths)); 1691 $q['name'] = $q['pagename']; 1692 $where .= " AND ($wpdb->posts.ID = '$reqpage')"; 1693 $reqpage_obj = get_page($reqpage); 1694 if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) { 1695 $this->is_attachment = true; 1696 $this->is_page = true; 1697 $q['attachment_id'] = $reqpage; 1698 } 1699 } 1700 } elseif ('' != $q['attachment']) { 1701 $q['attachment'] = str_replace('%2F', '/', urlencode(urldecode($q['attachment']))); 1702 $attach_paths = '/' . trim($q['attachment'], '/'); 1703 $q['attachment'] = sanitize_title(basename($attach_paths)); 1704 $q['name'] = $q['attachment']; 1705 $where .= " AND $wpdb->posts.post_name = '" . $q['attachment'] . "'"; 1706 } 1707 1708 if ( $q['w'] ) 1709 $where .= " AND WEEK($wpdb->posts.post_date, 1)='" . $q['w'] . "'"; 1710 1711 if ( intval($q['comments_popup']) ) 1712 $q['p'] = absint($q['comments_popup']); 1713 1714 // If an attachment is requested by number, let it supercede any post number. 1715 if ( $q['attachment_id'] ) 1716 $q['p'] = absint($q['attachment_id']); 1717 1718 // If a post number is specified, load that post 1719 if ( $q['p'] ) { 1720 $where .= " AND {$wpdb->posts}.ID = " . $q['p']; 1721 } elseif ( $q['post__in'] ) { 1722 $post__in = implode(',', array_map( 'absint', $q['post__in'] )); 1723 $where .= " AND {$wpdb->posts}.ID IN ($post__in)"; 1724 } elseif ( $q['post__not_in'] ) { 1725 $post__not_in = implode(',', array_map( 'absint', $q['post__not_in'] )); 1726 $where .= " AND {$wpdb->posts}.ID NOT IN ($post__not_in)"; 1727 } 1728 1729 if ( is_numeric($q['post_parent']) ) 1730 $where .= $wpdb->prepare( " AND $wpdb->posts.post_parent = %d ", $q['post_parent'] ); 1731 1732 if ( $q['page_id'] ) { 1733 if ( ('page' != get_option('show_on_front') ) || ( $q['page_id'] != get_option('page_for_posts') ) ) { 1734 $q['p'] = $q['page_id']; 1735 $where = " AND {$wpdb->posts}.ID = " . $q['page_id']; 1736 } 1737 } 1738 1739 // If a search pattern is specified, load the posts that match 1740 if ( !empty($q['s']) ) { 1741 // added slashes screw with quote grouping when done early, so done later 1742 $q['s'] = stripslashes($q['s']); 1743 if ( !empty($q['sentence']) ) { 1744 $q['search_terms'] = array($q['s']); 1745 } else { 1746 preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $q['s'], $matches); 1747 $q['search_terms'] = array_map(create_function('$a', 'return trim($a, "\\"\'\\n\\r ");'), $matches[0]); 1748 } 1749 $n = !empty($q['exact']) ? '' : '%'; 1750 $searchand = ''; 1751 foreach( (array) $q['search_terms'] as $term) { 1752 $term = addslashes_gpc($term); 1753 $search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))"; 1754 $searchand = ' AND '; 1755 } 1756 $term = $wpdb->escape($q['s']); 1757 if (empty($q['sentence']) && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'] ) 1758 $search .= " OR ($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}')"; 1759 1760 if ( !empty($search) ) 1761 $search = " AND ({$search}) "; 1762 } 1763 1764 // Category stuff 1765 1766 if ( empty($q['cat']) || ($q['cat'] == '0') || 1767 // Bypass cat checks if fetching specific posts 1768 $this->is_singular ) { 1769 $whichcat = ''; 1770 } else { 1771 $q['cat'] = ''.urldecode($q['cat']).''; 1772 $q['cat'] = addslashes_gpc($q['cat']); 1773 $cat_array = preg_split('/[,\s]+/', $q['cat']); 1774 $q['cat'] = ''; 1775 $req_cats = array(); 1776 foreach ( (array) $cat_array as $cat ) { 1777 $cat = intval($cat); 1778 $req_cats[] = $cat; 1779 $in = ($cat > 0); 1780 $cat = abs($cat); 1781 if ( $in ) { 1782 $q['category__in'][] = $cat; 1783 $q['category__in'] = array_merge($q['category__in'], get_term_children($cat, 'category')); 1784 } else { 1785 $q['category__not_in'][] = $cat; 1786 $q['category__not_in'] = array_merge($q['category__not_in'], get_term_children($cat, 'category')); 1787 } 1788 } 1789 $q['cat'] = implode(',', $req_cats); 1790 } 1791 1792 if ( !empty($q['category__in']) ) { 1793 $groupby = "{$wpdb->posts}.ID"; 1794 } 1795 1796 if ( !empty($q['category__in']) ) { 1797 $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) "; 1798 $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'category' "; 1799 $include_cats = "'" . implode("', '", $q['category__in']) . "'"; 1800 $whichcat .= " AND $wpdb->term_taxonomy.term_id IN ($include_cats) "; 1801 } 1802 1803 if ( !empty($q['category__not_in']) ) { 1804 if ( $wpdb->has_cap( 'subqueries' ) ) { 1805 $cat_string = "'" . implode("', '", $q['category__not_in']) . "'"; 1806 $whichcat .= " AND $wpdb->posts.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy = 'category' AND tt.term_id IN ($cat_string) )"; 1807 } else { 1808 $ids = get_objects_in_term($q['category__not_in'], 'category'); 1809 if ( is_wp_error( $ids ) ) 1810 $ids = array(); 1811 if ( is_array($ids) && count($ids > 0) ) { 1812 $out_posts = "'" . implode("', '", $ids) . "'"; 1813 $whichcat .= " AND $wpdb->posts.ID NOT IN ($out_posts)"; 1814 } 1815 } 1816 } 1817 1818 // Category stuff for nice URLs 1819 if ( '' != $q['category_name'] && !$this->is_singular ) { 1820 $reqcat = get_category_by_path($q['category_name']); 1821 $q['category_name'] = str_replace('%2F', '/', urlencode(urldecode($q['category_name']))); 1822 $cat_paths = '/' . trim($q['category_name'], '/'); 1823 $q['category_name'] = sanitize_title(basename($cat_paths)); 1824 1825 $cat_paths = '/' . trim(urldecode($q['category_name']), '/'); 1826 $q['category_name'] = sanitize_title(basename($cat_paths)); 1827 $cat_paths = explode('/', $cat_paths); 1828 $cat_path = ''; 1829 foreach ( (array) $cat_paths as $pathdir ) 1830 $cat_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title($pathdir); 1831 1832 //if we don't match the entire hierarchy fallback on just matching the nicename 1833 if ( empty($reqcat) ) 1834 $reqcat = get_category_by_path($q['category_name'], false); 1835 1836 if ( !empty($reqcat) ) 1837 $reqcat = $reqcat->term_id; 1838 else 1839 $reqcat = 0; 1840 1841 $q['cat'] = $reqcat; 1842 1843 $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) "; 1844 $whichcat = " AND $wpdb->term_taxonomy.taxonomy = 'category' "; 1845 $in_cats = array($q['cat']); 1846 $in_cats = array_merge($in_cats, get_term_children($q['cat'], 'category')); 1847 $in_cats = "'" . implode("', '", $in_cats) . "'"; 1848 $whichcat .= "AND $wpdb->term_taxonomy.term_id IN ($in_cats)"; 1849 $groupby = "{$wpdb->posts}.ID"; 1850 } 1851 1852 // Tags 1853 if ( '' != $q['tag'] ) { 1854 if ( strpos($q['tag'], ',') !== false ) { 1855 $tags = preg_split('/[,\s]+/', $q['tag']); 1856 foreach ( (array) $tags as $tag ) { 1857 $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db'); 1858 $q['tag_slug__in'][] = $tag; 1859 } 1860 } else if ( preg_match('/[+\s]+/', $q['tag']) ) { 1861 $tags = preg_split('/[+\s]+/', $q['tag']); 1862 foreach ( (array) $tags as $tag ) { 1863 $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db'); 1864 $q['tag_slug__and'][] = $tag; 1865 } 1866 } else { 1867 $q['tag'] = sanitize_term_field('slug', $q['tag'], 0, 'post_tag', 'db'); 1868 $q['tag_slug__in'][] = $q['tag']; 1869 } 1870 } 1871 1872 if ( !empty($q['tag__in']) || !empty($q['tag_slug__in']) ) { 1873 $groupby = "{$wpdb->posts}.ID"; 1874 } 1875 1876 if ( !empty($q['tag__in']) ) { 1877 $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) "; 1878 $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'post_tag' "; 1879 $include_tags = "'" . implode("', '", $q['tag__in']) . "'"; 1880 $whichcat .= " AND $wpdb->term_taxonomy.term_id IN ($include_tags) "; 1881 $reqtag = is_term( $q['tag__in'][0], 'post_tag' ); 1882 if ( !empty($reqtag) ) 1883 $q['tag_id'] = $reqtag['term_id']; 1884 } 1885 1886 if ( !empty($q['tag_slug__in']) ) { 1887 $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) INNER JOIN $wpdb->terms ON ($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id) "; 1888 $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'post_tag' "; 1889 $include_tags = "'" . implode("', '", $q['tag_slug__in']) . "'"; 1890 $whichcat .= " AND $wpdb->terms.slug IN ($include_tags) "; 1891 $reqtag = get_term_by( 'slug', $q['tag_slug__in'][0], 'post_tag' ); 1892 if ( !empty($reqtag) ) 1893 $q['tag_id'] = $reqtag->term_id; 1894 } 1895 1896 if ( !empty($q['tag__not_in']) ) { 1897 if ( $wpdb->has_cap( 'subqueries' ) ) { 1898 $tag_string = "'" . implode("', '", $q['tag__not_in']) . "'"; 1899 $whichcat .= " AND $wpdb->posts.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy = 'post_tag' AND tt.term_id IN ($tag_string) )"; 1900 } else { 1901 $ids = get_objects_in_term($q['tag__not_in'], 'post_tag'); 1902 if ( is_wp_error( $ids ) ) 1903 $ids = array(); 1904 if ( is_array($ids) && count($ids > 0) ) { 1905 $out_posts = "'" . implode("', '", $ids) . "'"; 1906 $whichcat .= " AND $wpdb->posts.ID NOT IN ($out_posts)"; 1907 } 1908 } 1909 } 1910 1911 // Tag and slug intersections. 1912 $intersections = array('category__and' => 'category', 'tag__and' => 'post_tag', 'tag_slug__and' => 'post_tag'); 1913 foreach ($intersections as $item => $taxonomy) { 1914 if ( empty($q[$item]) ) continue; 1915 1916 if ( $item != 'category__and' ) { 1917 $reqtag = is_term( $q[$item][0], 'post_tag' ); 1918 if ( !empty($reqtag) ) 1919 $q['tag_id'] = $reqtag['term_id']; 1920 } 1921 1922 $taxonomy_field = $item == 'tag_slug__and' ? 'slug' : 'term_id'; 1923 1924 $q[$item] = array_unique($q[$item]); 1925 $tsql = "SELECT p.ID FROM $wpdb->posts p INNER JOIN $wpdb->term_relationships tr ON (p.ID = tr.object_id) INNER JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) INNER JOIN $wpdb->terms t ON (tt.term_id = t.term_id)"; 1926 $tsql .= " WHERE tt.taxonomy = '$taxonomy' AND t.$taxonomy_field IN ('" . implode("', '", $q[$item]) . "')"; 1927 $tsql .= " GROUP BY p.ID HAVING count(p.ID) = " . count($q[$item]); 1928 1929 $post_ids = $wpdb->get_col($tsql); 1930 1931 if ( count($post_ids) ) 1932 $whichcat .= " AND $wpdb->posts.ID IN (" . implode(', ', $post_ids) . ") "; 1933 else { 1934 $whichcat = " AND 0 = 1"; 1935 break; 1936 } 1937 } 1938 1939 // Taxonomies 1940 if ( $this->is_tax ) { 1941 if ( '' != $q['taxonomy'] ) { 1942 $taxonomy = $q['taxonomy']; 1943 $tt[$taxonomy] = $q['term']; 1944 $terms = get_terms($q['taxonomy'], array('slug'=>$q['term'])); 1945 } else { 1946 foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) { 1947 if ( isset($t->query_var) && '' != $q[$t->query_var] ) { 1948 $terms = get_terms($taxonomy, array('slug'=>$q[$t->query_var])); 1949 if ( !is_wp_error($terms) ) 1950 break; 1951 } 1952 } 1953 } 1954 if ( is_wp_error($terms) || empty($terms) ) { 1955 $whichcat = " AND 0 "; 1956 } else { 1957 foreach ( $terms as $term ) 1958 $term_ids[] = $term->term_id; 1959 $post_ids = get_objects_in_term($term_ids, $taxonomy); 1960 if ( !is_wp_error($post_ids) && count($post_ids) ) { 1961 $whichcat .= " AND $wpdb->posts.ID IN (" . implode(', ', $post_ids) . ") "; 1962 $post_type = 'any'; 1963 $q['post_status'] = 'publish'; 1964 $post_status_join = true; 1965 } else { 1966 $whichcat = " AND 0 "; 1967 } 1968 } 1969 } 1970 1971 // Author/user stuff 1972 1973 if ( empty($q['author']) || ($q['author'] == '0') ) { 1974 $whichauthor=''; 1975 } else { 1976 $q['author'] = ''.urldecode($q['author']).''; 1977 $q['author'] = addslashes_gpc($q['author']); 1978 if (strpos($q['author'], '-') !== false) { 1979 $eq = '!='; 1980 $andor = 'AND'; 1981 $q['author'] = explode('-', $q['author']); 1982 $q['author'] = '' . absint($q['author'][1]); 1983 } else { 1984 $eq = '='; 1985 $andor = 'OR'; 1986 } 1987 $author_array = preg_split('/[,\s]+/', $q['author']); 1988 $whichauthor .= " AND ($wpdb->posts.post_author ".$eq.' '.absint($author_array[0]); 1989 for ($i = 1; $i < (count($author_array)); $i = $i + 1) { 1990 $whichauthor .= ' '.$andor." $wpdb->posts.post_author ".$eq.' '.absint($author_array[$i]); 1991 } 1992 $whichauthor .= ')'; 1993 } 1994 1995 // Author stuff for nice URLs 1996 1997 if ('' != $q['author_name']) { 1998 if (strpos($q['author_name'], '/') !== false) { 1999 $q['author_name'] = explode('/',$q['author_name']); 2000 if ($q['author_name'][count($q['author_name'])-1]) { 2001 $q['author_name'] = $q['author_name'][count($q['author_name'])-1];#no trailing slash 2002 } else { 2003 $q['author_name'] = $q['author_name'][count($q['author_name'])-2];#there was a trailling slash 2004 } 2005 } 2006 $q['author_name'] = sanitize_title($q['author_name']); 2007 $q['author'] = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE user_nicename='".$q['author_name']."'"); 2008 $whichauthor .= " AND ($wpdb->posts.post_author = ".absint($q['author']).')'; 2009 } 2010 2011 // MIME-Type stuff for attachment browsing 2012 2013 if ( isset($q['post_mime_type']) && '' != $q['post_mime_type'] ) 2014 $whichmimetype = wp_post_mime_type_where($q['post_mime_type']); 2015 2016 $where .= $search.$whichcat.$whichauthor.$whichmimetype; 2017 2018 if ( empty($q['order']) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC')) ) 2019 $q['order'] = 'DESC'; 2020 2021 // Order by 2022 if ( empty($q['orderby']) ) { 2023 $q['orderby'] = "$wpdb->posts.post_date ".$q['order']; 2024 } else { 2025 // Used to filter values 2026 $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand'); 2027 if ( !empty($q['meta_key']) ) { 2028 $allowed_keys[] = $q['meta_key']; 2029 $allowed_keys[] = 'meta_value'; 2030 } 2031 $q['orderby'] = urldecode($q['orderby']); 2032 $q['orderby'] = addslashes_gpc($q['orderby']); 2033 $orderby_array = explode(' ',$q['orderby']); 2034 if ( empty($orderby_array) ) 2035 $orderby_array[] = $q['orderby']; 2036 $q['orderby'] = ''; 2037 for ($i = 0; $i < count($orderby_array); $i++) { 2038 // Only allow certain values for safety 2039 $orderby = $orderby_array[$i]; 2040 switch ($orderby) { 2041 case 'menu_order': 2042 break; 2043 case 'ID': 2044 $orderby = "$wpdb->posts.ID"; 2045 break; 2046 case 'rand': 2047 $orderby = 'RAND()'; 2048 break; 2049 case $q['meta_key']: 2050 case 'meta_value': 2051 $orderby = "$wpdb->postmeta.meta_value"; 2052 break; 2053 default: 2054 $orderby = "$wpdb->posts.post_" . $orderby; 2055 } 2056 if ( in_array($orderby_array[$i], $allowed_keys) ) 2057 $q['orderby'] .= (($i == 0) ? '' : ',') . $orderby; 2058 } 2059 // append ASC or DESC at the end 2060 if ( !empty($q['orderby'])) 2061 $q['orderby'] .= " {$q['order']}"; 2062 2063 if ( empty($q['orderby']) ) 2064 $q['orderby'] = "$wpdb->posts.post_date ".$q['order']; 2065 } 2066 2067 if ( $this->is_attachment ) { 2068 $where .= " AND $wpdb->posts.post_type = 'attachment'"; 2069 } elseif ($this->is_page) { 2070 $where .= " AND $wpdb->posts.post_type = 'page'"; 2071 } elseif ($this->is_single) { 2072 $where .= " AND $wpdb->posts.post_type = 'post'"; 2073 } elseif ( 'any' == $post_type ) { 2074 $where .= ''; 2075 } else { 2076 $where .= " AND $wpdb->posts.post_type = '$post_type'"; 2077 } 2078 2079 if ( isset($q['post_status']) && '' != $q['post_status'] ) { 2080 $statuswheres = array(); 2081 $q_status = explode(',', $q['post_status']); 2082 $r_status = array(); 2083 $p_status = array(); 2084 if ( in_array( 'draft' , $q_status ) ) 2085 $r_status[] = "$wpdb->posts.post_status = 'draft'"; 2086 if ( in_array( 'pending', $q_status ) ) 2087 $r_status[] = "$wpdb->posts.post_status = 'pending'"; 2088 if ( in_array( 'future' , $q_status ) ) 2089 $r_status[] = "$wpdb->posts.post_status = 'future'"; 2090 if ( in_array( 'inherit' , $q_status ) ) 2091 $r_status[] = "$wpdb->posts.post_status = 'inherit'"; 2092 if ( in_array( 'private', $q_status ) ) 2093 $p_status[] = "$wpdb->posts.post_status = 'private'"; 2094 if ( in_array( 'publish', $q_status ) ) 2095 $r_status[] = "$wpdb->posts.post_status = 'publish'"; 2096 2097 if ( empty($q['perm'] ) || 'readable' != $q['perm'] ) { 2098 $r_status = array_merge($r_status, $p_status); 2099 unset($p_status); 2100 } 2101 2102 if ( !empty($r_status) ) { 2103 if ( !empty($q['perm'] ) && 'editable' == $q['perm'] && !current_user_can("edit_others_{$post_type}s") ) 2104 $statuswheres[] = "($wpdb->posts.post_author = $user_ID " . "AND (" . join( ' OR ', $r_status ) . "))"; 2105 else 2106 $statuswheres[] = "(" . join( ' OR ', $r_status ) . ")"; 2107 } 2108 if ( !empty($p_status) ) { 2109 if ( !empty($q['perm'] ) && 'readable' == $q['perm'] && !current_user_can("read_private_{$post_type}s") ) 2110 $statuswheres[] = "($wpdb->posts.post_author = $user_ID " . "AND (" . join( ' OR ', $p_status ) . "))"; 2111 else 2112 $statuswheres[] = "(" . join( ' OR ', $p_status ) . ")"; 2113 } 2114 if ( $post_status_join ) { 2115 $join .= " LEFT JOIN $wpdb->posts AS p2 ON ($wpdb->posts.post_parent = p2.ID) "; 2116 foreach ( $statuswheres as $index => $statuswhere ) 2117 $statuswheres[$index] = "($statuswhere OR ($wpdb->posts.post_status = 'inherit' AND " . str_replace($wpdb->posts, 'p2', $statuswhere) . "))"; 2118 } 2119 foreach ( $statuswheres as $statuswhere ) 2120 $where .= " AND $statuswhere"; 2121 } elseif ( !$this->is_singular ) { 2122 $where .= " AND ($wpdb->posts.post_status = 'publish'"; 2123 2124 if ( is_admin() ) 2125 $where .= " OR $wpdb->posts.post_status = 'future' OR $wpdb->posts.post_status = 'draft' OR $wpdb->posts.post_status = 'pending'"; 2126 2127 if ( is_user_logged_in() ) { 2128 $where .= current_user_can( "read_private_{$post_type}s" ) ? " OR $wpdb->posts.post_status = 'private'" : " OR $wpdb->posts.post_author = $user_ID AND $wpdb->posts.post_status = 'private'"; 2129 } 2130 2131 $where .= ')'; 2132 } 2133 2134 // postmeta queries 2135 if ( ! empty($q['meta_key']) || ! empty($q['meta_value']) ) 2136 $join .= " LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id) "; 2137 if ( ! empty($q['meta_key']) ) 2138 $where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_key = %s ", $q['meta_key']); 2139 if ( ! empty($q['meta_value']) ) { 2140 if ( ! isset($q['meta_compare']) || empty($q['meta_compare']) || ! in_array($q['meta_compare'], array('=', '!=', '>', '>=', '<', '<=')) ) 2141 $q['meta_compare'] = '='; 2142 2143 $where .= $wpdb->prepare("AND $wpdb->postmeta.meta_value {$q['meta_compare']} %s ", $q['meta_value']); 2144 } 2145 2146 // Apply filters on where and join prior to paging so that any 2147 // manipulations to them are reflected in the paging by day queries. 2148 if ( !$q['suppress_filters'] ) { 2149 $where = apply_filters('posts_where', $where); 2150 $join = apply_filters('posts_join', $join); 2151 } 2152 2153 // Paging 2154 if ( empty($q['nopaging']) && !$this->is_singular ) { 2155 $page = absint($q['paged']); 2156 if (empty($page)) { 2157 $page = 1; 2158 } 2159 2160 if ( empty($q['offset']) ) { 2161 $pgstrt = ''; 2162 $pgstrt = ($page - 1) * $q['posts_per_page'] . ', '; 2163 $limits = 'LIMIT '.$pgstrt.$q['posts_per_page']; 2164 } else { // we're ignoring $page and using 'offset' 2165 $q['offset'] = absint($q['offset']); 2166 $pgstrt = $q['offset'] . ', '; 2167 $limits = 'LIMIT ' . $pgstrt . $q['posts_per_page']; 2168 } 2169 } 2170 2171 // Comments feeds 2172 if ( $this->is_comment_feed && ( $this->is_archive || $this->is_search || !$this->is_singular ) ) { 2173 if ( $this->is_archive || $this->is_search ) { 2174 $cjoin = "LEFT JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) $join "; 2175 $cwhere = "WHERE comment_approved = '1' $where"; 2176 $cgroupby = "GROUP BY $wpdb->comments.comment_id"; 2177 } else { // Other non singular e.g. front 2178 $cjoin = "LEFT JOIN $wpdb->posts ON ( $wpdb->comments.comment_post_ID = $wpdb->posts.ID )"; 2179 $cwhere = "WHERE post_status = 'publish' AND comment_approved = '1'"; 2180 $cgroupby = ''; 2181 } 2182 2183 if ( !$q['suppress_filters'] ) { 2184 $cjoin = apply_filters('comment_feed_join', $cjoin); 2185 $cwhere = apply_filters('comment_feed_where', $cwhere); 2186 $cgroupby = apply_filters('comment_feed_groupby', $cgroupby); 2187 } 2188 2189 $this->comments = (array) $wpdb->get_results("SELECT $distinct $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby ORDER BY comment_date_gmt DESC LIMIT " . get_option('posts_per_rss')); 2190 $this->comment_count = count($this->comments); 2191 2192 $post_ids = array(); 2193 2194 foreach ($this->comments as $comment) 2195 $post_ids[] = (int) $comment->comment_post_ID; 2196 2197 $post_ids = join(',', $post_ids); 2198 $join = ''; 2199 if ( $post_ids ) 2200 $where = "AND $wpdb->posts.ID IN ($post_ids) "; 2201 else 2202 $where = "AND 0"; 2203 } 2204 2205 $orderby = $q['orderby']; 2206 2207 // Apply post-paging filters on where and join. Only plugins that 2208 // manipulate paging queries should use these hooks. 2209 if ( !$q['suppress_filters'] ) { 2210 $where = apply_filters('posts_where_paged', $where); 2211 $groupby = apply_filters('posts_groupby', $groupby); 2212 $join = apply_filters('posts_join_paged', $join); 2213 $orderby = apply_filters('posts_orderby', $orderby); 2214 $distinct = apply_filters('posts_distinct', $distinct); 2215 $limits = apply_filters( 'post_limits', $limits ); 2216 2217 if ( ! empty($q['meta_key']) ) 2218 $fields = "$fields, $wpdb->postmeta.meta_value"; 2219 2220 $fields = apply_filters('posts_fields', $fields); 2221 } 2222 2223 // Announce current selection parameters. For use by caching plugins. 2224 do_action( 'posts_selection', $where . $groupby . $orderby . $limits . $join ); 2225 2226 // Filter again for the benefit of caching plugins. Regular plugins should use the hooks above. 2227 if ( !$q['suppress_filters'] ) { 2228 $where = apply_filters('posts_where_request', $where); 2229 $groupby = apply_filters('posts_groupby_request', $groupby); 2230 $join = apply_filters('posts_join_request', $join); 2231 $orderby = apply_filters('posts_orderby_request', $orderby); 2232 $distinct = apply_filters('posts_distinct_request', $distinct); 2233 $fields = apply_filters('posts_fields_request', $fields); 2234 $limits = apply_filters( 'post_limits_request', $limits ); 2235 } 2236 2237 if ( ! empty($groupby) ) 2238 $groupby = 'GROUP BY ' . $groupby; 2239 if ( !empty( $orderby ) ) 2240 $orderby = 'ORDER BY ' . $orderby; 2241 $found_rows = ''; 2242 if ( !empty($limits) ) 2243 $found_rows = 'SQL_CALC_FOUND_ROWS'; 2244 2245 $this->request = " SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits"; 2246 if ( !$q['suppress_filters'] ) 2247 $this->request = apply_filters('posts_request', $this->request); 2248 2249 $this->posts = $wpdb->get_results($this->request); 2250 // Raw results filter. Prior to status checks. 2251 if ( !$q['suppress_filters'] ) 2252 $this->posts = apply_filters('posts_results', $this->posts); 2253 2254 if ( !empty($this->posts) && $this->is_comment_feed && $this->is_singular ) { 2255 $cjoin = apply_filters('comment_feed_join', ''); 2256 $cwhere = apply_filters('comment_feed_where', "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'"); 2257 $comments_request = "SELECT $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere ORDER BY comment_date_gmt DESC LIMIT " . get_option('posts_per_rss'); 2258 $this->comments = $wpdb->get_results($comments_request); 2259 $this->comment_count = count($this->comments); 2260 } 2261 2262 if ( !empty($limits) ) { 2263 $found_posts_query = apply_filters( 'found_posts_query', 'SELECT FOUND_ROWS()' ); 2264 $this->found_posts = $wpdb->get_var( $found_posts_query ); 2265 $this->found_posts = apply_filters( 'found_posts', $this->found_posts ); 2266 $this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']); 2267 } 2268 2269 // Check post status to determine if post should be displayed. 2270 if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) { 2271 $status = get_post_status($this->posts[0]); 2272 //$type = get_post_type($this->posts[0]); 2273 if ( ('publish' != $status) ) { 2274 if ( ! is_user_logged_in() ) { 2275 // User must be logged in to view unpublished posts. 2276 $this->posts = array(); 2277 } else { 2278 if (in_array($status, array('draft', 'pending')) ) { 2279 // User must have edit permissions on the draft to preview. 2280 if (! current_user_can('edit_post', $this->posts[0]->ID)) { 2281 $this->posts = array(); 2282 } else { 2283 $this->is_preview = true; 2284 $this->posts[0]->post_date = current_time('mysql'); 2285 } 2286 } else if ('future' == $status) { 2287 $this->is_preview = true; 2288 if (!current_user_can('edit_post', $this->posts[0]->ID)) { 2289 $this->posts = array ( ); 2290 } 2291 } else { 2292 if (! current_user_can('read_post', $this->posts[0]->ID)) 2293 $this->posts = array(); 2294 } 2295 } 2296 } 2297 2298 if ( $this->is_preview && current_user_can( "edit_{$post_type}", $this->posts[0]->ID ) ) 2299 $this->posts[0] = apply_filters('the_preview', $this->posts[0]); 2300 } 2301 2302 // Put sticky posts at the top of the posts array 2303 $sticky_posts = get_option('sticky_posts'); 2304 if ( $this->is_home && $page <= 1 && !empty($sticky_posts) && !$q['caller_get_posts'] ) { 2305 $num_posts = count($this->posts); 2306 $sticky_offset = 0; 2307 // Loop over posts and relocate stickies to the front. 2308 for ( $i = 0; $i < $num_posts; $i++ ) { 2309 if ( in_array($this->posts[$i]->ID, $sticky_posts) ) { 2310 $sticky_post = $this->posts[$i]; 2311 // Remove sticky from current position 2312 array_splice($this->posts, $i, 1); 2313 // Move to front, after other stickies 2314 array_splice($this->posts, $sticky_offset, 0, array($sticky_post)); 2315 // Increment the sticky offset. The next sticky will be placed at this offset. 2316 $sticky_offset++; 2317 // Remove post from sticky posts array 2318 $offset = array_search($sticky_post->ID, $sticky_posts); 2319 array_splice($sticky_posts, $offset, 1); 2320 } 2321 } 2322 2323 // Fetch sticky posts that weren't in the query results 2324 if ( !empty($sticky_posts) ) { 2325 $stickies__in = implode(',', array_map( 'absint', $sticky_posts )); 2326 $stickies = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE $wpdb->posts.ID IN ($stickies__in)" ); 2327 /** @todo Make sure post is published or viewable by the current user */ 2328 foreach ( $stickies as $sticky_post ) { 2329 if ( 'publish' != $sticky_post->post_status ) 2330 continue; 2331 array_splice($this->posts, $sticky_offset, 0, array($sticky_post)); 2332 $sticky_offset++; 2333 } 2334 } 2335 } 2336 2337 if ( !$q['suppress_filters'] ) 2338 $this->posts = apply_filters('the_posts', $this->posts); 2339 2340 update_post_caches($this->posts); 2341 2342 $this->post_count = count($this->posts); 2343 if ($this->post_count > 0) { 2344 $this->post = $this->posts[0]; 2345 } 2346 2347 return $this->posts; 2348 } 2349 2350 /** 2351 * Setup the next post and iterate current post index. 2352 * 2353 * @since 1.5.0 2354 * @access public 2355 * 2356 * @return object Next post. 2357 */ 2358 function next_post() { 2359 2360 $this->current_post++; 2361 2362 $this->post = $this->posts[$this->current_post]; 2363 return $this->post; 2364 } 2365 2366 /** 2367 * Sets up the current post. 2368 * 2369 * Retrieves the next post, sets up the post, sets the 'in the loop' 2370 * property to true. 2371 * 2372 * @since 1.5.0 2373 * @access public 2374 * @uses $post 2375 * @uses do_action() Calls 'loop_start' if loop has just started 2376 */ 2377 function the_post() { 2378 global $post; 2379 $this->in_the_loop = true; 2380 $post = $this->next_post(); 2381 setup_postdata($post); 2382 2383 if ( $this->current_post == 0 ) // loop has just started 2384 do_action('loop_start'); 2385 } 2386 2387 /** 2388 * Whether there are more posts available in the loop. 2389 * 2390 * Calls action 'loop_end', when the loop is complete. 2391 * 2392 * @since 1.5.0 2393 * @access public 2394 * @uses do_action() Calls 'loop_start' if loop has just started 2395 * 2396 * @return bool True if posts are available, false if end of loop. 2397 */ 2398 function have_posts() { 2399 if ($this->current_post + 1 < $this->post_count) { 2400 return true; 2401 } elseif ($this->current_post + 1 == $this->post_count && $this->post_count > 0) { 2402 do_action('loop_end'); 2403 // Do some cleaning up after the loop 2404 $this->rewind_posts(); 2405 } 2406 2407 $this->in_the_loop = false; 2408 return false; 2409 } 2410 2411 /** 2412 * Rewind the posts and reset post index. 2413 * 2414 * @since 1.5.0 2415 * @access public 2416 */ 2417 function rewind_posts() { 2418 $this->current_post = -1; 2419 if ($this->post_count > 0) { 2420 $this->post = $this->posts[0]; 2421 } 2422 } 2423 2424 /** 2425 * Iterate current comment index and return comment object. 2426 * 2427 * @since 2.2.0 2428 * @access public 2429 * 2430 * @return object Comment object. 2431 */ 2432 function next_comment() { 2433 $this->current_comment++; 2434 2435 $this->comment = $this->comments[$this->current_comment]; 2436 return $this->comment; 2437 } 2438 2439 /** 2440 * Sets up the current comment. 2441 * 2442 * @since 2.2.0 2443 * @access public 2444 * @global object $comment Current comment. 2445 * @uses do_action() Calls 'comment_loop_start' hook when first comment is processed. 2446 */ 2447 function the_comment() { 2448 global $comment; 2449 2450 $comment = $this->next_comment(); 2451 2452 if ($this->current_comment == 0) { 2453 do_action('comment_loop_start'); 2454 } 2455 } 2456 2457 /** 2458 * Whether there are more comments available. 2459 * 2460 * Automatically rewinds comments when finished. 2461 * 2462 * @since 2.2.0 2463 * @access public 2464 * 2465 * @return bool True, if more comments. False, if no more posts. 2466 */ 2467 function have_comments() { 2468 if ($this->current_comment + 1 < $this->comment_count) { 2469 return true; 2470 } elseif ($this->current_comment + 1 == $this->comment_count) { 2471 $this->rewind_comments(); 2472 } 2473 2474 return false; 2475 } 2476 2477 /** 2478 * Rewind the comments, resets the comment index and comment to first. 2479 * 2480 * @since 2.2.0 2481 * @access public 2482 */ 2483 function rewind_comments() { 2484 $this->current_comment = -1; 2485 if ($this->comment_count > 0) { 2486 $this->comment = $this->comments[0]; 2487 } 2488 } 2489 2490 /** 2491 * Sets up the WordPress query by parsing query string. 2492 * 2493 * @since 1.5.0 2494 * @access public 2495 * 2496 * @param string $query URL query string. 2497 * @return array List of posts. 2498 */ 2499 function &query($query) { 2500 $this->parse_query($query); 2501 return $this->get_posts(); 2502 } 2503 2504 /** 2505 * Retrieve queried object. 2506 * 2507 * If queried object is not set, then the queried object will be set from 2508 * the category, tag, taxonomy, posts page, single post, page, or author 2509 * query variable. After it is set up, it will be returned. 2510 * 2511 * @since 1.5.0 2512 * @access public 2513 * 2514 * @return object 2515 */ 2516 function get_queried_object() { 2517 if (isset($this->queried_object)) { 2518 return $this->queried_object; 2519 } 2520 2521 $this->queried_object = NULL; 2522 $this->queried_object_id = 0; 2523 2524 if ($this->is_category) { 2525 $cat = $this->get('cat'); 2526 $category = &get_category($cat); 2527 if ( is_wp_error( $category ) ) 2528 return NULL; 2529 $this->queried_object = &$category; 2530 $this->queried_object_id = (int) $cat; 2531 } else if ($this->is_tag) { 2532 $tag_id = $this->get('tag_id'); 2533 $tag = &get_term($tag_id, 'post_tag'); 2534 if ( is_wp_error( $tag ) ) 2535 return NULL; 2536 $this->queried_object = &$tag; 2537 $this->queried_object_id = (int) $tag_id; 2538 } else if ($this->is_tax) { 2539 $tax = $this->get('taxonomy'); 2540 $slug = $this->get('term'); 2541 $term = &get_terms($tax, array('slug'=>$slug)); 2542 if ( is_wp_error($term) || empty($term) ) 2543 return NULL; 2544 $term = $term[0]; 2545 $this->queried_object = $term; 2546 $this->queried_object_id = $term->term_id; 2547 } else if ($this->is_posts_page) { 2548 $this->queried_object = & get_page(get_option('page_for_posts')); 2549 $this->queried_object_id = (int) $this->queried_object->ID; 2550 } else if ($this->is_single) { 2551 $this->queried_object = $this->post; 2552 $this->queried_object_id = (int) $this->post->ID; 2553 } else if ($this->is_page) { 2554 $this->queried_object = $this->post; 2555 $this->queried_object_id = (int) $this->post->ID; 2556 } else if ($this->is_author) { 2557 $author_id = (int) $this->get('author'); 2558 $author = get_userdata($author_id); 2559 $this->queried_object = $author; 2560 $this->queried_object_id = $author_id; 2561 } 2562 2563 return $this->queried_object; 2564 } 2565 2566 /** 2567 * Retrieve ID of the current queried object. 2568 * 2569 * @since 1.5.0 2570 * @access public 2571 * 2572 * @return int 2573 */ 2574 function get_queried_object_id() { 2575 $this->get_queried_object(); 2576 2577 if (isset($this->queried_object_id)) { 2578 return $this->queried_object_id; 2579 } 2580 2581 return 0; 2582 } 2583 2584 /** 2585 * PHP4 type constructor. 2586 * 2587 * Sets up the WordPress query, if parameter is not empty. 2588 * 2589 * @since 1.5.0 2590 * @access public 2591 * 2592 * @param string $query URL query string. 2593 * @return WP_Query 2594 */ 2595 function WP_Query ($query = '') { 2596 if (! empty($query)) { 2597 $this->query($query); 2598 } 2599 } 2600 } 2601 2602 /** 2603 * Redirect old slugs to the correct permalink. 2604 * 2605 * Attempts to find the current slug from the past slugs. 2606 * 2607 * @since 2.1.0 2608 * @uses $wp_query 2609 * @uses $wpdb 2610 * 2611 * @return null If no link is found, null is returned. 2612 */ 2613 function wp_old_slug_redirect () { 2614 global $wp_query; 2615 if ( is_404() && '' != $wp_query->query_vars['name'] ) : 2616 global $wpdb; 2617 2618 $query = "SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND meta_key = '_wp_old_slug' AND meta_value='" . $wp_query->query_vars['name'] . "'"; 2619 2620 // if year, monthnum, or day have been specified, make our query more precise 2621 // just in case there are multiple identical _wp_old_slug values 2622 if ( '' != $wp_query->query_vars['year'] ) 2623 $query .= " AND YEAR(post_date) = '{$wp_query->query_vars['year']}'"; 2624 if ( '' != $wp_query->query_vars['monthnum'] ) 2625 $query .= " AND MONTH(post_date) = '{$wp_query->query_vars['monthnum']}'"; 2626 if ( '' != $wp_query->query_vars['day'] ) 2627 $query .= " AND DAYOFMONTH(post_date) = '{$wp_query->query_vars['day']}'"; 2628 2629 $id = (int) $wpdb->get_var($query); 2630 2631 if ( !$id ) 2632 return; 2633 2634 $link = get_permalink($id); 2635 2636 if ( !$link ) 2637 return; 2638 2639 wp_redirect($link, '301'); // Permanent redirect 2640 exit; 2641 endif; 2642 } 2643 2644 /** 2645 * Setup global post data. 2646 * 2647 * @since 1.5.0 2648 * 2649 * @param object $post Post data. 2650 * @return bool True when finished. 2651 */ 2652 function setup_postdata($post) { 2653 global $id, $authordata, $day, $currentmonth, $page, $pages, $multipage, $more, $numpages; 2654 2655 $id = (int) $post->ID; 2656 2657 $authordata = get_userdata($post->post_author); 2658 2659 $day = mysql2date('d.m.y', $post->post_date); 2660 $currentmonth = mysql2date('m', $post->post_date); 2661 $numpages = 1; 2662 $page = get_query_var('page'); 2663 if ( !$page ) 2664 $page = 1; 2665 if ( is_single() || is_page() || is_feed() ) 2666 $more = 1; 2667 $content = $post->post_content; 2668 if ( strpos( $content, '<!--nextpage-->' ) ) { 2669 if ( $page > 1 ) 2670 $more = 1; 2671 $multipage = 1; 2672 $content = str_replace("\n<!--nextpage-->\n", '<!--nextpage-->', $content); 2673 $content = str_replace("\n<!--nextpage-->", '<!--nextpage-->', $content); 2674 $content = str_replace("<!--nextpage-->\n", '<!--nextpage-->', $content); 2675 $pages = explode('<!--nextpage-->', $content); 2676 $numpages = count($pages); 2677 } else { 2678 $pages[0] = $post->post_content; 2679 $multipage = 0; 2680 } 2681 return true; 2682 } 2683 2684 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Mar 23 16:23:02 2009 | Cross-referenced by PHPXref 0.7 |