Support » Plugin: Relevanssi - A Better Search » Fatal error — relevanssi_do_query

  • Resolved Matt Gibbs

    (@mgibbs189)


    Hey Mikko – FacetWP author here. Some users are reporting a PHP fatal error. Relates to the following code:

                $query = (object) array(
                    'is_admin' => false,
                    'query_vars' => array(
                        's' => $selected_values,
                        'paged' => 1,
                        'posts_per_page' => -1
                    )
                );
    
                relevanssi_do_query( $query );
    

    Error message:

    Fatal error: Call to undefined method stdClass::set() in /plugins/relevanssi/lib/search.php on line 1241

    Screenshot of code in question: http://d.pr/i/XjxdK

    Thanks

Viewing 13 replies - 1 through 13 (of 13 total)
  • Plugin Author Mikko Saari

    (@msaari)

    That’s because you can’t feed stdClass objects to relevanssi_do_query(), the function requires a WP_Query object – which will contain the set() method Relevanssi wants to use.

    So:

    $args = array(whatever);
    $query = new WP_Query($args);
    relevanssi_do_query($query);

    I really should add some checks for this in Relevanssi, at least to get more helpful error messages.

    @msaari when did this change? This exact approach worked flawlessly until just recently, and I can’t find the notice in the changelog…

    Plugin Author Mikko Saari

    (@msaari)

    It has always been the implicit assumption, because that’s what Relevanssi gets from WordPress. There’s a knowledge base article from 2011 that says “The function takes a WP_Query object as a parameter”…

    However, pre 1.15.0 Relevanssi didn’t use any of the member methods in WP_Query, just the variables. 1.15.0 was the first version to set the operator with $query->set(), causing the error. So until 1.15.0, you’ve been able to use a stdClass object, as long as you’ve set the necessary attributes.

    So far that’s the only place where Relevanssi is currently using WP_Query methods, but it’s assuming that several attributes are in place. I suppose I could have Relevanssi just directly set the variable instead of using the set() function, but then the problem is just passed later – the fact remains that Relevanssi expects a WP_Query, and passing one is the only way to be sure everything’s fine.

    The problematic line — $query->set("operator", $operator);
    wasn’t added until ~3.5.8, hence the issue.

    So it looks like now I’m going to have to do:

                $query = new WP_Query( array(
                    's' => $selected_values,
                    'paged' => 1,
                    'posts_per_page' => -1
                ) );
                $query->is_admin = false; // force Relevanssi to treat this as a non-ajax request
    
                relevanssi_do_query( $query );
    

    Which I’m guessing will be slower because the WP_Query will have to execute now, in addition to the normal relevanssi_do_query. Maybe there’s a better way?

    • This reply was modified 1 year, 10 months ago by  Matt Gibbs.

    @msaari did my last reply make sense? It amounts to 2 things:

    1. Forcing a WP_Query (instead of supporting a raw object) is a lot less efficient. The WP_Query automatically runs its DB request, as well as relevanssi_do_query. So a lot of wasted overhead.

    2. The addition of that ->set() on line 1241 broke backwards compatibility. Perhaps you could change it to ->query_vars['orderby'] until we can figure out a more optimal solution for #1.

    Plugin Author Mikko Saari

    (@msaari)

    Ah, I was looking at Premium versions. 1.15.0 in Premium equals 3.5.8 in free, yes.

    Actually, looking at the WP_Query source code, the constructor looks like this:

    public function __construct( $query = '' ) {
        if ( ! empty( $query ) ) {
            $this->query( $query );
        }
    }

    If you call $query = new WP_Query(); without any arguments, no query is run. You can then populate the necessary attributes, and pass the object to Relevanssi.

    That said, I can change that ->set() to just directly set the variable, but I can’t promise future compatibility – there may be times when it’s really necessary for Relevanssi to do something WP_Query specific with the query, and then I’m not going to worry too much about this, so for future compatibility it is better to use WP_Query object there.

    @msaari – sounds good, I’ll switch our add-on to WP_Query.

    If you don’t mind replacing ->set() too, as a temporary fix, it’ll help prevent issues for users still on older versions of our add-on.

    Thanks for your quick assistance!

    Plugin Author Mikko Saari

    (@msaari)

    Sure, I’ll make the change in the next version. Before that is out, you can point people in need of a hotfix to this version of search.php, which already contains the fix and can be used to replace the current lib/search.php.

    Roger that! 🙂

    Thanks to Mikko and Matt Gibbs. I updated to the latest free Relevanssi version and had this exact problem. Couldn’t see any reference to it in the change log, and so rolled back to the previous version.

    I’m also using relevanssi_do_query( $query );

    Now I have a clue what to fix.

    Plugin Author Mikko Saari

    (@msaari)

    There should be nothing to fix: just update to 3.5.10 and that should solve the issue. Does it?

    Wow, thanks a lot Mikko. Yes, it does solve the problem! There is now nothing to fix.

    Read your release notes and it looks like it would be smartest to convert to use a WP_Query object for the future, so I’ll follow through with this anyway.

Viewing 13 replies - 1 through 13 (of 13 total)
  • The topic ‘Fatal error — relevanssi_do_query’ is closed to new replies.