Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I am trying to get start and end dates for posts filtered, and I found the documentation for the 'posts_where' filter, I am just testing it so far, but when ever I add the filter, it seems to pull in the loop data for the main navigation (i.e. from wp_nav_menu())

I added:

<?php remove_filter('posts_where', 'uc_filter_where'); ?>

<?php wp_nav_menu(array('sort_column' => 'menu_order', 'menu_class' => 'nav', 'theme_location' => 'primary-menu')); ?>

in an attempt to clear out the where filter for the posts, but no such luck. Anyone explain to me what I am doing wrong.

share|improve this question
    
So you've got a uc_filter_where function that you only want to use on the main query? Or only for certain post type queries? –  Stephen Harris Jun 21 '12 at 16:00
    
Well, actually, I want to customize the taxonomy query. This occurs in the 'taxonomy.php'. I tried posting screenshots, but my measly reputation of 1 won't let me post images to the forum. Anyhow, when I add the filter, I get results including navigation items (an undesired result), when I use the default query it gives me what I want, but I need the custom query for filtering date ranges. Here's my function.php code: –  G896 Jun 21 '12 at 16:14
    
function _filter_where($where = "") { $where .= " AND post_date BETWEEN '" . $_GET[POSTS_START_DATE_NAME] . "' AND '" . $_GET[POSTS_END_DATE_NAME] . "'"; return $where; } add_filter('posts_where', 'filter_where');` –  G896 Jun 21 '12 at 16:15
    
This is the SQL string produced when the filter is added: SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10. Where '1=1'????? –  G896 Jun 21 '12 at 17:59

1 Answer 1

up vote 2 down vote accepted

So first of all you'll want to make sure that you want to and your WHERE clause in. posts_where will fire for (almost) every query so you want to be sure that you're adding it to the right one. This can be done with the use of conditional tags.

Note: The WHERE 1=1 is added because it means a valid WHERE expression is added, and can be extended using the posts_where filter (i.e by just adding AND X=Y ). Infact WordPress hardcodes the WHERE and adds in the conditionals - so it needs something to be there to be sure that the SQL query is valid

add_filter('posts_where', 'wpse55985_posts_where',10,2);
function wpse55985_posts_where($where, $query){
    global $wpdb;

    //$query is a WP_Query object

    if( $query->is_main_query() && is_tax('my-tax') ){
         //This is the main query for the 'my-tax' taxonomy page

         if( isset($_GET[POSTS_END_DATE_NAME]) && isset($_GET[POSTS_START_DATE_NAME]) ){
             //Variables are set.
             $start = $_GET[POSTS_START_DATE_NAME];
             $end = $_GET[POSTS_END_DATE_NAME];

             //Append our additional 'WHERE' clause
             $where .= $wpdb->prepare(
                 " AND {$wpdb->posts}.post_date BETWEEN %s AND %s ", $start,$end
             ) ;
         }
    }
    return $where
}

Explanation

  1. First of all use is_main_query() to check that this is the query that is the 'main' query for the page. The conditionals all relate to this main query. So I'm checking that this is the main query, and the query is for the taxonomy 'my-tax' - in particular that the 'my-tax' taxonomy page is being viewed. So the above should only filter posts on the my-tax taxonomy page. See is_tax(). Otherwise, we just return the $where clause without doing anything.

  2. Check that the $_GET variables you are after are set. You should really be registering custom query variables and using the $query->get() method than dealing with $_GET directly. If they aren't set, we don't alter the query.

  3. Use the $wpdb class to get the post table name and to safely prepare the query. See this Codex page, and the last part of this article. This part is vital to protect yourself form SQL injection.

Please note, I've not tested this, and there could be syntax errors.

share|improve this answer
    
First off, Stephen, thank you very much for you concerted effort. I don't think I've ever gotten such a great response in a help forum, like yours. Unfortunately, that approach produced the same results (i.e. a broken query) –  G896 Jun 21 '12 at 20:19
    
I am under the suspicion that this is resetting the entire query where statement. Because attachments as well as menu items are showing up in the results along with the posts. –  G896 Jun 21 '12 at 20:56
    
Stephen, nevermind, your code was kosher, it was a syntax goof on my part. I forgot to add the 3rd and 4th parameter to the filter method. Works like a charm =) Thanks so much! –  G896 Jun 21 '12 at 21:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.