Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Custom post type, query the title and meta field(s) WordPress

  • SOLVED

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.

Answers (1)

2010-10-22

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!