logo
Ask your WordPress questions! Pay money and get answers fast! (more info)

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.

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

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.

This question has been answered.

69developer | 10/22/10 at 10:19am Edit


(1) Possible Answers Submitted...

See a chronological view of answers?

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

  • avatar
    Last edited:
    10/22/10
    2:36pm
    Rares Cosma says:

    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);


    Note: 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!

This question has expired.





Current status of this question: Completed



Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.