• We have a website which displays classes, a custom post type. Each class can have an expiration date (unix timestamp).

    I have the following code which worked in the past, which is simply meant to exclude expired classes from the search results page (and many other places of the website):

    function class_hide_expired_frontend( $query ) {
    	if ( is_admin() ) return;
    
    	// Do not filter secondary queries, only the main query and search queries
    	if ( !$query->is_main_query() && !$query->is_search ) return;
    
    	// Do not alter the existing meta_query if another filter is applied
    	if ( $query->get('meta_query') ) return;
    
    	// If the query affects classes, exclude expired ones
    	if ( $query->get('post_type') == 'class' || $query->is_search() || $query->get('taxonomy') == 'class-group' ) {
    		$query->set( 'meta_query', array(
    			'relation' => 'OR',
    			array(
    				'key' => 'date-timestamp',
    				'value' => time(),
    				'compare' => '>',
    			),
    			array(
    				'key' => 'date-timestamp',
    				'value' => '0',
    				'compare' => '=',
    			),
    		));
    	}
    
    	return $query;
    }
    add_action( "pre_get_posts", 'class_hide_expired_frontend', 90 );

    The above meta_query checks that the “date-timestamp” field (expiration date) is either 0 (no expiration) or greater than the current time.

    This code seems to be ignored when using Better Search. I assume this is because Better Search modifies the SQL statements directly and is incompatible with meta_query.

    Do you have any suggestions or alternatives?

    Thanks

    https://wordpress.org/plugins/better-search/

Viewing 4 replies - 1 through 4 (of 4 total)
  • Plugin Author WebberZone

    (@webberzone)

    Hi,

    Yes that is correct. Better Search uses its own SQL query.

    However, please see this gist on using meta fields as additional parameters with Github.

    https://gist.github.com/ajaydsouza/767215093a24bafb903a

    Also, do you have seamless mode on?

    Thread Starter radgh

    (@radgh)

    Yes I am using seamless mode.

    Thanks for the example on Gist. I couldn’t get it to work though. It seems the filters are not being called. Got any ideas?

    Here’s my settings:

    General – http://i.imgur.com/x0c5Rhb.jpg
    Search Results 1/2 – http://i.imgur.com/LZn6xl0.jpg
    Search Results 2/2 – http://i.imgur.com/wFIaf3L.jpg

    The page I am testing on is:

    http://willamalane.org/?s=lil

    Some of the classes shown, such as “Junior Turbos: Lil Dribblers”, have expired. We’re trying to hide them from that page, for now I’ve simply made them say “This class expired on ____”.

    Here’s what I was trying, which seemed to have no effect on the search page. It should have killed the page to display the where statement (var_dump, exit). The SQL itself hasn’t been tested yet, but it couldn’t be reached, so I can’t exactly test it yet.

    function class_hide_expired_bsearch_join( $join ) {
    	global $wpdb;
    
    	$join = $join . "\n  LEFT JOIN {$wpdb->postmeta} <code>class_date</code> ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id";
    	$join = $join . "\n  LEFT JOIN {$wpdb->postmeta} <code>always_show</code> ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id";
    
    	return $join;
    }
    function class_hide_expired_bsearch_where( $where ) {
    	global $wpdb;
    
    	$time = time();
    
    	$where = $where . "\n
    	AND (
    		{$wpdb->posts}.post_type != 'class'
    		OR (
    			<code>class_date</code>.meta_key = 'date-timestamp'
    			AND (
    				<code>class_date</code>.meta_value = 0
    				OR
    				<code>class_date</code>.meta_value > {$time}
    			)
    		) OR (
    			<code>always_show</code>.meta_key = 'always-show'
    			AND
    			<code>always_show</code>.meta_value = 'on'
    		)
    	)";
    
    	// Let's take a look at the WHERE statement
    	echo "<pre>";
    	var_dump($where);
    	exit;
    
    	return $where;
    }
    add_filter( 'bsearch_posts_join', 'class_hide_expired_bsearch_join' );
    add_filter( 'bsearch_posts_where', 'class_hide_expired_bsearch_where' );
    Thread Starter radgh

    (@radgh)

    The code tags shown above are meant to be grave symbols… The forums added them.

    Plugin Author Ajay

    (@ajay)

    I’m not sure exactly on how your class data is set up. I assume it’s a post type called class with extra meta fields which have the the date of the class?

    Are you in a position of installing Query Monitor plugin and checking the complete query that is generated on the search results page?

    I usually find it easier to debug once you’ve got the full sql query to run in phpMyAdmin and seeing what results turn up.

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Using pre_get_posts / meta_query on search page?’ is closed to new replies.