WordPress.org

Ready to get started?Download WordPress

Forums

Relevanssi - A Better Search
Compatibility with WPML (19 posts)

  1. AmirHelzer
    Member
    Posted 3 years ago #

    When Relevanssi and WPML are installed together, search results are no longer filtered by language.

    I'm responsible for WPML and want to work with you on this so that Relevanssi search results are language-specific.

    Would you be interested in this?

    http://wordpress.org/extend/plugins/relevanssi/

  2. Richard Vencu
    Member
    Posted 3 years ago #

    Nice. I just read this plugin offers a filter hook relevanssi_hits_filter

    Maybe you can do something around that?

  3. AmirHelzer
    Member
    Posted 3 years ago #

    Can you give me a quick push and post a list to where that filter is described?

  4. Richard Vencu
    Member
    Posted 3 years ago #

    Apparently there are more filters available (relevanssi_where looks promising), see the plugin FAQ http://wordpress.org/extend/plugins/relevanssi/faq/

    I just found this plugin and started to experiment with it...

  5. Richard Vencu
    Member
    Posted 3 years ago #

    so I am not the author of Relevanssi, sorry if I sounded misleading

  6. Mikko Saari
    Member
    Plugin Author

    Posted 3 years ago #

    Well, I'm the author of Relevanssi and I'm very interested in getting Relevanssi and WPML to work together (I use WPML myself), I just haven't had the time to do it yet.

    The relevanssi_hits_filter is one way to approach it. It gives you a list of hits found with the query, so it's possible to go through them and discard the hits that are in the wrong language.

    It's on line 570 of Relevanssi 2.6.

    $filter_data = array($hits, $q);
    	$hits_filters_applied = apply_filters('relevanssi_hits_filter', $filter_data);
    	$hits = $hits_filters_applied[0];

    The first part of the data is an array of post objects, the second is the search query. You need to return an array containing an array of post objects in index 0.

    That's one way to approach it. Then there's relevanssi_where, which allows you to modify query restrictions. That's what gets slapped in the end of the MySQL query that finds the hits. You could add some MySQL code that restricts the search to only current language (essentially in the shape of " AND doc IN (list of allowed post ID's) " or " AND doc NOT IN (list of forbidden post ID's) ".

    If you can come up with something that makes Relevanssi work with WPML, I'd be delighted to add it to Relevanssi core if necessary, since WPML is such a significant plugin. If WPML is active, user could choose to restrict the search to the active language or to search all languages.

    You can email me directly at mikko at mikkosaari.fi.

  7. Richard Vencu
    Member
    Posted 3 years ago #

    Hi, I got another issue with the combination of those plugins.

    If you try this search: http://www.dentfix.ro/?s=dentist+copil

    you get this error:

    Catchable fatal error: Object of class WP_Error could not be converted to string in /home/dentfixr/public_html/wp-content/plugins/sitepress-multilingual-cms/sitepress.class.php on line 3514

    But all is OK when doing this search: http://www.dentfix.ro/?s=dentist+copil&lang=en

  8. Mikko Saari
    Member
    Plugin Author

    Posted 3 years ago #

    Hmm, that sounds like a WPML problem... In any case, I'm going to work on Relevanssi-WPML relations and got some good tips from WPML folks.

  9. Richard Vencu
    Member
    Posted 3 years ago #

    Nice. Filtering on the current language might eliminate this problem too since I noticed all searches with hits in only one language are performed correctly, while those with hits in more languages might just break.

    So if you want to add as an option seaching in multiple languages this issue should be addressed.

  10. Richard Vencu
    Member
    Posted 3 years ago #

    My simple solution to return hits only in the current language:

    add_filter ('relevanssi_hits_filter','relevanssi_wpml_filter_hits');
    
    function relevanssi_wpml_filter_hits($hits) {
    
        $filtered_hits = array();
        foreach ($hits[0] as $hit) {
            if ($hit->ID == icl_object_id($hit->ID, 'post',false,ICL_LANGUAGE_CODE))
                    $filtered_hits[] = $hit;
            if ($hit->ID == icl_object_id($hit->ID, 'page',false,ICL_LANGUAGE_CODE))
                    $filtered_hits[] = $hit;
            if ($hit->ID == icl_object_id($hit->ID, 'customposttype1',false,ICL_LANGUAGE_CODE))
                    $filtered_hits[] = $hit;
            if ($hit->ID == icl_object_id($hit->ID, 'customposttype2',false,ICL_LANGUAGE_CODE))
                    $filtered_hits[] = $hit;
            if ($hit->ID == icl_object_id($hit->ID, 'customposttype3',false,ICL_LANGUAGE_CODE))
                    $filtered_hits[] = $hit;
        }
        $filtered = array($filtered_hits,$hits[1]);
        return $filtered;
    }

    I noticed that filtering the search this way, the fatal error issue described above has dissapeared.

    If more info can be useful to spot the issue, I also noticed that the fatal error happens for unfiltered results in all languages, in any desktop theme. But it works fine with the mobile themes under WPTouch Pro :)

  11. Mikko Saari
    Member
    Plugin Author

    Posted 3 years ago #

    I just wrote the code for WPML-Relevanssi integration today. My solution is similar to yours, though I grab the id's of entries in current language from the db and compare to that.

    I'll release 2.7 soon, though I've got a couple of more features to add, and then Relevanssi and WPML will work together.

  12. Richard Vencu
    Member
    Posted 3 years ago #

    Yes, I suppose the DB stuff will work faster... and the code would not depend on the names of the custom post types defined.

  13. Richard Vencu
    Member
    Posted 3 years ago #

    After some good sleep I realized that the function can be wrote much shorter and that WPML guys are going to preserve the icl_object_id function even if they decide at some point to change the database structure.

    function relevanssi_wpml_filter_hits($hits) {
    
        $filtered_hits = array();
        foreach ($hits[0] as $hit) {
            if ($hit->ID == icl_object_id($hit->ID, $hit->post_type,false,ICL_LANGUAGE_CODE))
                    $filtered_hits[] = $hit;
        }
        return array($filtered_hits,$hits[1]);
    }
  14. Mikko Saari
    Member
    Plugin Author

    Posted 3 years ago #

    Nice solution! I'll use this code in Relevanssi. Thanks!

  15. Mikko Saari
    Member
    Plugin Author

    Posted 3 years ago #

    The version 2.7 is now out and has automatic WPML support.

  16. Richard Vencu
    Member
    Posted 3 years ago #

    Hi, I upgraded to v2.7 but for some reason if I disable my integration code the module behaves just like 2.6 with no integration. Please explain a bit how did you do it maybe I can debug the issue.

  17. Richard Vencu
    Member
    Posted 3 years ago #

    Hi again,

    I found the code and I fixed it, here is my result:

    add_action( 'after_setup_theme', 'relevanssi_custom_setup' );
    
    function relevanssi_custom_setup(){
        if (defined('ICL_LANGUAGE_CODE'))
    	add_filter('relevanssi_hits_filter', 'relevanssi_wpml_filter');
    }
    
    // thanks to rvencu
    function relevanssi_wpml_filter($data) {
    	if (function_exists(icl_object_id)) {
    		$filtered_hits = array();
        	foreach ($data[0] as $hit) {
            	if ($hit->ID == icl_object_id($hit->ID, $hit->post_type,false,ICL_LANGUAGE_CODE))
                    $filtered_hits[] = $hit;
    	    }
    	    return array($filtered_hits,$data[1]);
    	}
    	else {
    		return $data;
    	}
    }

    Note that you missed a $hits[1] instead of $data[1].
    Also at the time your plugin loads the filter does not get applied. If waiting until after the theme setup is helping the process. At least in my installation it works like this.

  18. Mikko Saari
    Member
    Plugin Author

    Posted 3 years ago #

    Thanks for being so alert! However, just upgrade to 2.7.1, that fixes it.

    There were two problems: function_exists needs quotes around the function name and the if(defined()) contruction doesn't work unless you do something like you did.

    The $hits[1] doesn't matter, because that return value is never used, it's only to give some extra information to the filter.

    I'll probably fix it to something like this eventually, but right now, 2.7.1 works and 2.7 doesn't.

  19. Richard Vencu
    Member
    Posted 3 years ago #

    Perfect. Thanks and congratulations for such a great plugin!

Topic Closed

This topic has been closed to new replies.

About this Plugin

About this Topic

Tags