Support » Developing with WordPress » searching posts to return results based on visual content

  • My search results are not coming out how I need them to. For example if I search for ';' or 'nbsp', WordPress finds matches in posts that should not match. The problem is that there are posts that have html entities which include ‘;’ or ‘nbsp’ even though in the visual content there are none. If there are none in the visual content then I don’t want them to be matches. Is there a way to run html_entity_decode() on the post content before wordpress searches it for matches?
    I looking for a solution that doesn’t involve filtering the search results that wordpress returns because doing so seems very inefficient. There must be some way to limit WordPress’ search to exclude the html entities. The solution should also not involve changing any of the core wordpress functions.
    I’ve tried:

    function maus_content_filter( $content ) {
        $content = html_entity_decode($content);
        // run your code on $content and
        return $content;
    }
    add_filter( 'the_content', 'maus_content_filter');

    But it doesn’t work. I think because the wordpress search is not dependent on the ‘the_content’ action. Any suggestions?

    Meyer

Viewing 3 replies - 1 through 3 (of 3 total)
  • Moderator bcworkz

    (@bcworkz)

    I agree that post processing search query results would be very inefficient. I’m not sure there is a choice. The search query is executed with SQL. It’s not possible to apply PHP functions like html_entity_decode() during a SQL query. However, SQL does have its own set of functions that can be used in queries. I’ve no idea if a similar function is available or not.

    If composing a query using such a function is possible, the way to apply it to search queries is through the “posts_where” filter, which allows you to alter the entire SQL WHERE clause. All post queries use this filter, so you must ensure you are only changing the appropriate query. The entire query object is passed by reference to your filter callback, so you can check the query_vars property to verify you are altering the correct queries.

    Thanks, I understant the idea you are saying but I’m not sure how to implement such a filter. Say I found such an SQL function, what would the code look like in order to use the function to change the wordpress search result. Would I need to make my own query or would applying this filter automatically effect the wordpress search query.
    Also what would the code look like to check the query variables.

    function decode_entities($query){
    //what goes here??
    }
    addfilter('posts_where','decode_entities);

    Is this what you mean?
    Meyer

    • This reply was modified 3 months, 2 weeks ago by  bcworkz. Reason: code fixed
    Moderator bcworkz

    (@bcworkz)

    Close, a little more fleshed out but still incomplete:

    function decode_entities( $where, $query ){
      global $wpdb;
      if ( $query->is_main_query() && $query->query_vars['s'] != '') {
        $where = " AND {$wpdb->posts}.post_content LIKE '{$query->query_vars['s']}'";
      }
      return $where;
    }
    add_filter('posts_where','decode_entities', 10, 2 );

    Whatever is returned from decode_entitites() is appended to the default SQL null WHERE clause: WHERE 1=1. The clause in the above code is minimal, there are generally several conditions to specify, like post type, status, searching also in titles and excerpts, etc. Also lacking is whatever function that might decode HTML.

    Instead of specifying a complete WHERE clause, you might want to search and replace portions of the default clause passed to our callback as $where. For example:
    $where = str_replace('wp_post.post_content', 'HTML_DECODE( wp_post.post_content )', $where );

    HTML_DECODE is something I made up for the example, I don’t think there is such a function. Your other option is to declare a custom SQL decode function, sent to mySQL using global $wpdb object methods. The other issue is I don’t think you can apply a function to a column being searched in the manner used in my str_replace() example. I think you need to create a decoded view from which to get matching posts. I’m not an SQL expert, don’t take my word for anything SQL related.

    The SQL required to do this is getting pretty complicated. You might be better off composing your own original SQL executed through $wpdb methods and forget about WP_Query and its filters. You would then be looking at a completely custom search handler instead of trying to modify the WP search functionality.

    Or go back to post processing with PHP despite the inefficiency.

Viewing 3 replies - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.