[wp-hackers] Query by multiple custom fields/taxonomies, MySQL LIMIT
Matthew Gerring
mgerring at emrl.com
Fri Feb 12 21:48:18 UTC 2010
Hello all,
I'm working on a plugin for a client that allows narrowing of search results, i.e. querying by multiple custom taxonomies and meta keys at once. So far as I can determine there's no built in way to do this (as in get only posts that are in both one taxonomy AND another, or are both in a category AND have a particular tag, or have a certain meta value AND another meta value of a different key, and so forth).
My problem is that I don't know SQL that well, and I'm wondering if there's a means of setting up the record set I'm returning to automatically work with WordPress paging. If not, I was wondering how you get the total size of the record set regardless of the LIMIT statement so I can set up paging manually. I also want to know in general if there's a better way to do what I'm doing. Here's the code:
function sw_custom_query($input) {
global $wpdb;
$input = wp_parse_args($input);
//var_dump($input);
$bio_meta_keys = array('dob','loc');
$bio_tax = array('faith-tradition','alive','type');
foreach ($input as $key=>$value) {
if ( in_array($key,$bio_meta_keys) || in_array($input['orderby'], $bio_meta_keys) ) {
if (in_array($key,$bio_meta_keys)) {
$input['where'] .= ' AND '.$key.'.meta_value = \''.$value.'\'';
}
if ($key == 'orderby') { $key = $value; }
if ( in_array($input['orderby'], $bio_meta_keys) ) {
$input['select'] .= ', '.$key.'.meta_value';
$input['order'] .= ' ORDER BY '.$key.'.meta_value';
}
$input['from'] .= ', '.$wpdb->postmeta.' '.$key.' ';
$input['where'] .= ' AND '.$key.'.meta_key = \''.$key.'\'';
$input['where'] .= ' AND p.id = '.$key.'.post_id';
}
if (in_array($key,$bio_tax) || in_array($input['orderby'], $bio_tax)) {
if ($key == 'orderby') { $key = $value; }
$modkey = str_replace('-','_',$key);
if ( in_array($key,$bio_tax) ) {
$sort = ' AND '.$modkey.'t.slug = \''.$value.'\'';
} else {
$sort = '';
}
if ( in_array($input['orderby'], $bio_tax) ) {
$input['select'] = ', '.$modkey.'t.slug';
$input['order'] .= ' ORDER BY '.$modkey.'t.slug';
}
$input['from'] .= ', '.$wpdb->terms.' '.$modkey.'t';
$input['from'] .= ', '.$wpdb->term_taxonomy.' '.$modkey.'tt';
$input['from'] .= ', '.$wpdb->term_relationships.' '.$modkey.'tr ';
$input['where'] .= ' AND p.id = '.$modkey.'tr.object_id';
$input['where'] .= ' AND '.$modkey.'t.term_id = '.$modkey.'tt.term_id';
$input['where'] .= ' AND '.$modkey.'tr.term_taxonomy_id = '.$modkey.'tt.term_taxonomy_id';
$input['where'] .= ' AND ('.$modkey.'tt.taxonomy = \''.$key.'\' AND '.$modkey.'tt.term_id = '.$modkey.'t.term_id'.$sort.' )';
}
}
if ( $input['orderby'] == 'name' ) { $input['order'] = " ORDER BY p.post_title "; }
$querystr .= "SELECT p.*".$input['select'];
$querystr .= " from $wpdb->posts p, $wpdb->postmeta meta";
$querystr .= $input['from'];
$querystr .= " WHERE p.id = meta.post_id";
$querystr .= $input['where'];
$querystr .="
AND meta.meta_key = 'mf_page_type'
AND meta.meta_value = 'Biography'
AND p.post_type = 'page'
AND p.post_status = 'publish'
";
$querystr .= $input['order'];
$querystr .=" LIMIT 5, 5"; // This is here for testing purposes- no variable input here yet.
//echo $querystr;
return $querystr;
}
Thanks for any help you can provide.
Matthew
More information about the wp-hackers
mailing list