3

I have multiples custom field in a post type. i can save data, update and display, all fine. now I'm doing the search engine. as it is a library, it must be possible to search in specific fields (custom field), publisher, country, etc. Here the code I have for publisher...

i open a variable

    function register_query_vars( $vars ) {
    $vars[] = 'publisher'; //
    return $vars;
} 
add_filter( 'query_vars', 'register_query_vars' );

search form by publisher in shortcode

function publisher_search() {
    add_shortcode( 'search_form_publisher', 'search_form_publisher' );
}
add_action( 'init', 'publisher_search' );

form:

function search_form_publisher( $atts ){
 
    $output = '<form action="' . esc_url( home_url() ) . '" method="get" role="search">';
    $output .= '<input type="text" name="publisher" value="' . get_search_query() . '" class="field" placeholder="Search..."/>';
    $output .= '<input type="hidden" name="post_type" value="books" />';
    $output .= '<input type="submit" value="Search!" class="button" />';
    $output .= '</form>';
    return $output;
}

so far, all good. when searching, the following url is built:

http://localhost/library/?publisher=search_term&post_type=books

which uses the archive-{post-type}.php template

$args = array(
  'post_type'      => 'books',
  'post_status'    => 'publish',
  'meta_query'     => array(
    array(
      'key'     => 'publisher',
      'value'   => get_query_var('publisher'),
      'compare' => 'LIKE',

    ) 
  )
);

// The Query
$the_query = new WP_Query( $args );

// The Loop
if ( $the_query->have_posts() ) {

    while ( $the_query->have_posts() ) : $the_query->the_post(); 
        // Your code here

   publisher();
       
    endwhile;

} else {
        echo 'no posts found';
}
/* Restore original Post Data */
wp_reset_postdata();

I print the value of the custom field publisher like this, its work well:

function publisher() {
    global $wp_query;
    $post = $wp_query->post;
    $publisher = get_post_meta($post->ID, 'publisher', true);
    if (!empty($publisher)) {
        echo $publisher;
    }
}

The problem is, however, that the query does not return any results. the print is this:

Array ( [post_type] => books [post_status] => publish [meta_query] => Array ( [0] => Array ( [key] => publisher [value] => Harvard [compare] => LIKE ) ) )

that is, if it collects the value of the search term. I have tried many codes that I have found on the internet but none of them work. I think that a function that adds a posts_search filter, but the ones I have tried do not work.

I would appreciate your help to resolve the issue.I'm lost. Thank you!!

7
  • Your code seems fine (although in the publisher() function, you should just use get_post() to get the current post or get_the_ID() to get just the post ID), so are you 100% sure there are books posts with the meta publisher containing Harvard/harvard in the value? Try echo $the_query->request; and see if the SQL is good. And try adding 'suppress_filters' => true to your $args just to see if a code is modifying your args - does suppressing filters return any results?
    – Sally CJ
    Commented Jan 9, 2021 at 9:42
  • 1
    And I think it'd be much better if you use a custom taxonomy (named publisher) than using the post meta. Because taxonomies are better suited at grouping things together and taxonomy queries also run faster than meta queries.
    – Sally CJ
    Commented Jan 9, 2021 at 9:52
  • 1
    okay. thank you for the recommendations. It helped me a lot to do echo $ the_query-> request because although the SQL query it does is fine, the point is that it is not looking at the correct table because I have a specific table for the custom fields.
    – Oox
    Commented Jan 9, 2021 at 18:14
  • The query is: SELECT SQL_CALC_FOUND_ROWS wp_8_posts.ID FROM wp_8_posts INNER JOIN wp_8_postmeta ON ( wp_8_posts.ID = wp_8_postmeta.post_id ) WHERE 1=1 AND ( ( wp_8_postmeta.meta_key = 'publisher' AND wp_8_postmeta.meta_value LIKE '{}Harvard{}' ) ) AND wp_8_posts.post_type = 'books' AND ((wp_8_posts.post_status = 'publish')) GROUP BY wp_8_posts.ID ORDER BY wp_8_posts.post_date DESC LIMIT 0, 10. My table with custom field is `wp_8_postmeta_books' See: link
    – Oox
    Commented Jan 9, 2021 at 18:19
  • so probably if i need a post_search filter??
    – Oox
    Commented Jan 9, 2021 at 18:22

1 Answer 1

0

After thinking about the problem, I found the simplest solution, do a direct query using $wpdb

in archive-{post-type}.php

<?php 

global $wpdb;
$meta_key = get_query_var('publisher');
$result = $wpdb->get_results("
    SELECT  * 
    FROM  " . $wpdb->prefix. "postmeta_books 
    WHERE publisher LIKE  '%$meta_key%' 
");
foreach( $result as $results ) {

        echo $results->publisher;
        echo '<br/>';
        

    }
?>

It is the basic query, it needs to be refined but I wanted to share it to close the question. of course work very well.

1
  • 1
    Your SQL query is vulnerable - use wpdb::prepare() to prepare the query for safe execution, and you should also use wpdb::esc_like() with the LIKE clause.
    – Sally CJ
    Commented Jan 10, 2021 at 5:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.