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