I have a custom post type 'memberlist'
I have many custom meta fields.
I need to query the custom post type and search for a 'keyword' in the post title and one of the custom meta fields 'member_tags'. But if the keyword exisits in both the post title and member_tags field, only want to return as one item and not two.
Rares Cosma answers:
Hello again,
You can use this function to perform the search:
function search_cpt_by_post_and_meta_fields($args) {
// Database abstraction
global $wpdb;
// Default arguments
$defaults = array(
'post_type' => 'post',
'post_fields_to_search' => false,
'meta_fields_to search' => false,
'search_term' => false
);
// Extract arguments for easier access
extract(wp_parse_args($args, $defaults));
if(($post_fields_to_search or $meta_fields_to_search) and $search_term) {
$ids = array();
// Query part 0 - SELECT statement
$query = "SELECT DISTINCT $wpdb->posts.ID
FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE ($wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = '$post_type') AND (";
// Query part 1 - Search post fields
$where_parts = array();
if(is_array($post_fields_to_search)) {
foreach($post_fields_to_search as $field) {
$where_parts[] = "$wpdb->posts.$field LIKE '%$search_term%'";
}
}
// Query part 2 - Search meta fields
if(is_array($meta_fields_to_search)) {
foreach($meta_fields_to_search as $field) {
$where_parts[] = "( $wpdb->postmeta.meta_key = '$field' AND $wpdb->postmeta.meta_value LIKE '%$search_term%' )";
}
}
if(count($where_parts)) $query .= implode(' OR ', $where_parts);
// Query last part - ORDER Statement
$query .= ") ORDER BY $wpdb->posts.ID ASC";
$results = $wpdb->get_results($query, ARRAY_A);
// Parse the results
foreach($results as $result){
$ids[] = $result['ID'];
}
return $ids;
}
return false;
}
The function accepts 4 arguments: the post type, the post fields to search, the post meta fields to search and the search term.
Call it like this:
$args = array(
'post_type' => 'memberlist',
'post_fields_to_search' => array('post_title'),
'meta_fields_to_search' => array('member_tags'),
'search_term' => 'hello'
);
$post_ids = search_cpt_by_post_and_meta_fields($args);
<strong>Note:</strong> You can easily alter the arguments to search to additional post fields or meta fields. For example, if you want to search the post title as well as post content:
$args = array(
'post_type' => 'memberlist',
'post_fields_to_search' => array('post_title', 'post_content'),
'meta_fields_to_search' => array('member_tags'),
'search_term' => 'hello'
);
$post_ids = search_cpt_by_post_and_meta_fields($args);
After getting the post ids you can easily display the data using a custom loop:
foreach($post_ids as $post_id) {
$post = get_post($post_id);
setup_postdata($post);
// Use template tags like the_content() or the_title()
}
Thanks!