Support » Plugin: The Events Calendar » Fatal Error with WP Query

  • There is a bug with the latest version of TEC that doesn’t play nice with the main WP query. There are multiple people on here reporting it however without a lot of details so hopefully this helps resolve the bug. If you have a standard WP query like below it throws an error like so.

    Fatal error: Uncaught Error: Call to a member function is_main_query() on null in D:\Websites\momentum\wp-content\plugins\the-events-calendar\src\functions\template-tags\general.php:1694 Stack trace: #0 D:\Websites\momentum\wp-content\plugins\the-events-calendar\src\Tribe\Query.php(163): tribe_is_events_front_page() #1 D:\Websites\momentum\wp-includes\class-wp-hook.php(286): Tribe__Events__Query::parse_query(Object(WP_Query)) #2 D:\Websites\momentum\wp-includes\class-wp-hook.php(310): WP_Hook->apply_filters(NULL, Array) #3 D:\Websites\momentum\wp-includes\plugin.php(515): WP_Hook->do_action(Array) #4 D:\Websites\momentum\wp-includes\class-wp-query.php(1006): do_action_ref_array(‘parse_query’, Array) #5 D:\Websites\momentum\wp-includes\class-wp-query.php(1621): WP_Query->parse_query() #6 D:\Websites\momentum\wp-includes\class-wp-query.php(3222): WP_Query->get_posts() #7 D:\Websites\momentum\wp-includes\class-wp-query.php(3328): WP_Query->query(Array) #8 D:\Websites\momentum\wp-content\themes\momentum\parts\home-blog-excerp in D:\Websites\momentum\wp-content\plugins\the-events-calendar\src\functions\template-tags\general.php on line 1694

    <?php
              $temp = $wp_query;
              $wp_query = null;
              $wp_query = new WP_Query(
                array(
                    'posts_per_page' => 4,
                    'paged' => $paged
                  )
                );
            ?>
    
            <?php if ($wp_query->have_posts()) : while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
    
              <article <?php post_class('BlogIntroWrap'); ?> role="article" itemscope itemtype="http://schema.org/BlogPosting">
              
            
                  <?php the_excerpt(); ?>
    
              </article> <!-- /article -->
    
            <?php endwhile; endif; ?>
    
            <?php $wp_query = null; $wp_query = $temp; ?>
            <?php wp_reset_postdata(); ?>
Viewing 12 replies - 1 through 12 (of 12 total)
  • It turns out this breaks anytime when your theme has a WP_query that already has the following line
    $wp_query = null;

    I’m also seeing this error since updating to 4.6.9

    Likewise I’m seeing this with v4.6.9. Rolling back to v4.6.8 works as a workaround. I was able to recode my website without using $wp_query = null; and confirmed that resolves the error with The Event Calendar 4.6.9.

    Plugin Author Victor Zarranz

    (@vicskf)

    Hi There!

    Thanks for taking your time to report this.

    @austinginder‘s approach of not modifying the $wp_query global is the best way to tackle this. In general, modifying that object is a bad practice and can lead to problems with lots of plugins – not just ours – so must be done with extreme care and only when necessary.

    I hope that helps.

    Best,
    Victor

    I’m a bit worried about this answer, this is a VERY common technique that is used to assign the WP query to a temp value and then put it back in order to get the post_nav_link function to perform correctly.

    I agree that modifying the wp_query is a bad idea, however this temporary storage of the variable has been used in a lot of themes, you are going to get a lot of reports start to come in on this. The fact that even when you have the setting to not include TEC in the main query it still blows up is a major issue to brush off. I have used this technique for probably 4 years 100 + sites and never had a plugin conflict

    https://wordpress.stackexchange.com/questions/20424/wp-query-and-next-posts-link

    https://wordpress.stackexchange.com/questions/160175/pagination-on-a-wp-query-not-showing-navigation-links

    • This reply was modified 1 year, 8 months ago by  nickfmc.
    • This reply was modified 1 year, 8 months ago by  nickfmc.

    I’d like to echo @nickfmc‘s reply. My site has been working for more than three years now and nulls $wp_query temporarily in order to run (many) custom queries on custom post types. I also have used this technique many times and never had an issue with any plugin.

    Same issue here. And this is a major issue because this is pretty serious because this is actually a RECOMMENDED practice. Example here by a highly reputable Stack Exchange user.

    Also, @vicskf, I think there’s confusion. If someone is using the code that @nickfmc posted, it is good practice because it is NOT modifying the $wp_query global data. If you check it closely, the code is assigning $wp_query to a temp var, doing a separate query using $wp_query, then re-assigning the original $wp_query right back to the way it was.

    • This reply was modified 1 year, 8 months ago by  onetrev. Reason: fix typos
    Plugin Author Barry

    (@barryhughes-1)

    Hey folks,

    There are a lot of great points here — let me try to address some of them and add some additional context.

    And this is a major issue because this is pretty serious because this is actually a RECOMMENDED practice. Example here by a highly reputable Stack Exchange user.

    I’m all for functional solutions and your collective experiences show this particular approach does work in a lot of situations (many bad practices do) … but let’s also keep in mind that this is not an official recommendation, regardless of how high the poster’s reputation currently is (remember also, he originally shared that tip something like 5 years ago).

    If someone is using the code that @nickfmc posted, it is good practice because it is NOT modifying the $wp_query global data. If you check it closely, the code is assigning $wp_query to a temp var, doing a separate query using $wp_query, then re-assigning the original $wp_query right back to the way it was.

    That side-steps a lot of important detail. Let’s break this down a little more and focus on this section of the code that @nickfmc shared:

    $wp_query = null;
    
    $wp_query = new WP_Query(
    	array(
    		'posts_per_page' => 4,
    		'paged' => $paged
    	)
    );

    So, we’re dealing with the global $wp_query variable here and we’re setting it to null. We then create a brand new WP_Query object and assign it back to that same global variable. It’s important to understand – and perhaps it isn’t obvious – that the second assignment doesn’t happen instantly. The chain of events is actually more like this:

    • The global $wp_query variable is set to null
    • A new query object is created
      • Lots of events take place during the creation process…
      • …the global $wp_query remains null through all this
    • Once the new object is finally created, only then do we update the global $wp_query object so that it is no longer null

    Our plugin (but I would hazard to say it is not alone) hooks into a number of the many events that take place during creation of the new query. It quite reasonably expects the global $wp_query object to contain a valid query object – not necessarily the main query object but certainly a valid query and instead it finds null.

    That’s why this is a bad practice and it’s telling that you will not observe the same thing in any default themes (Twenty Fifteen … Seventeen etc) that ship with WordPress.

    Iā€™m a bit worried about this answer, this is a VERY common technique that is used to assign the WP query to a temp value

    I agree both that the prevalence of this technique is common and that it is worrying. In general, we try not to code around bad practices from other themes/plugins but we’re practical people and absolutely strive for a smooth experience for as many users as possible.

    That to say, we’re not closed to making some changes to accommodate this sort of thing but I can’t guarantee it and we’ll need to discuss internally. I’ll do my best to drop by with an update once we’ve done so šŸ™‚

    Do let me know if you have questions on any of the above.

    Plugin Author Barry

    (@barryhughes-1)

    Just to add, for clarity – if you must alter the the global $wp_query var, then so long as it is replaced with a reference to a different query object I believe The Events Calendar will accommodate that pretty gracefully.

    Setting it to null or to anything that is not an object of the type WP_Query, however, is a path to chaos and should be avoided (nor is it ever necessary, so far as I can see) šŸ™‚

    Well it’s out there in the wild as a known work around from reputable sources and if TEC worked how it was prior to adding the option to include in the main WP query is it not possible to wrap the added code that breaks in an if option is checked statement, I would argue that your plugin running checks etc when the WP_Query is running even when there is no TEC data anywhere on that page is a waste of resources. I have probably 10 paid accounts of TEC but the support of late has been bullish to say the least with a lot of, ohh well it’s your issue. – https://css-tricks.com/snippets/wordpress/paginate-custom-post-types/

    Thanks for the detailed follow up @barryhughes-1. I appreciate it. And I agree this should be very concerning for TEC regardless of best / recommended practice argument. The main StackExchance (WP Dev) source for how to do pagination for custom queries has 169 votes!

    Further, to clarify, themes like Twenty Seventeen don’t do this because they don’t have custom main blog pages setup. But if you do need to do more than just have a plain blog home page, say, query for the first 3 posts, then query for 3 posts in X category, my understanding is it is actually BEST (even if hacky) to work with the $wp_query object. If not, because you are dealing with WP posts (not custom post types, in that case, yes for sure, don’t touch $wp_query!!), you get funky stuff happening, including pagination not working as expected. That’s why you see so many StackExchange / WP Forum questions about this issue.

    Plugin Author Barry

    (@barryhughes-1)

    Hi @nickfmc,

    I’m sorry you feel our support is bullish, that’s not our intention by any means. We do our best to be clear and thoughtful and in case it was lost in the detail, I’ll emphasize that we are not opposed to working around this pattern, but it’s also something that merits some discussion internally first of all.

    I would argue that your plugin running checks etc when the WP_Query is running even when there is no TEC data anywhere on that page is a waste of resources

    There are probably areas where we can tighten things up and we’re continually working to identify and address them, but let’s remember that:

    • Typically, in any single request, there isn’t just one WP_Query-powered query – there are lots of them
    • We don’t know if event data is being queried for unless we look at those queries – to do that, we need to hook in to them
    • We also have solid reasons for looking at queries besides the main WP_Query … for example, widgets or custom event queries may be used outside of event archives

    The performance impact of these checks is minimal: if it’s unrelated to event data we bow out as quickly as possible without further interference.

    But if you do need to do more than just have a plain blog home page, say, query for the first 3 posts, then query for 3 posts in X category, my understanding is it is actually BEST (even if hacky) to work with the $wp_query object.

    That’s a good note, @onetrev.

    Agreed – there’s nothing intrinsically wrong or bad about working with the global $wp_query object to learn about its properties or creating new WP_Query objects to obtain the posts you need. No argument there.

    I think it’s fair to say however that overriding the global $wp_query object unnecessarily is frowned upon at best and that setting it to null (which is the core problem here) is absolutely a bad practice.

Viewing 12 replies - 1 through 12 (of 12 total)
  • The topic ‘Fatal Error with WP Query’ is closed to new replies.