#56952 closed defect (bug) (fixed)
cache_users() not defined when calling get_user without field parameter or using all_with_meta or all
Reported by: | carazo | Owned by: | TimothyBlynJacobs |
---|---|---|---|
Milestone: | 6.1.1 | Priority: | normal |
Severity: | major | Version: | 6.1 |
Component: | Users | Keywords: | has-patch has-testing-info commit fixed-major i18n-change |
Focuses: | performance | Cc: |
Description
Good morning,
I have found that in WordPress 6.1 when I call get_users without the field parameter (or using fields = all or fields = all_with_meta) I get a fatal error.
I have been reading the code and it raise here:
Line 843 in file wp-includes/class-wp-user-query.php: cache_users( $this->results );
It seems this function is not defined there.
Could you have a look?
Thanks!
Attachments (1)
Change History (29)
#2
@
2 years ago
- Keywords needs-patch removed
- Resolution set to worksforme
- Status changed from new to closed
#3
@
2 years ago
- Resolution worksforme deleted
- Status changed from closed to reopened
@subrataemfluence,
I was calling this function inside this plugin in version 0.5, here: https://plugins.trac.wordpress.org/browser/woo-products-restricted-users/tags/0.5/class-wpru-metabox.php
In line 95, the error appeared there.
#4
@
2 years ago
I am also experiencing cache_users
not being defined when calling get_user
on 6.1.
Under some conditions, my plugin calls get_users
when initialized on the front end. In this context the plugin has loaded, but pluggable.php has not yet. Calling it without manually including wp-includes/pluggable.php
results in a fatal error.
I believe the issue is with the context of the call and not the content
#5
@
2 years ago
- Milestone changed from Awaiting Review to 6.1.1
- Owner set to TimothyBlynJacobs
- Status changed from reopened to accepted
Moving to 6.1.1, I don't think this should be unsupported usage.
#6
@
2 years ago
- Keywords has-patch added
I've attached a patch that would:
- Prevent fatal errors if
get_users()
is called before pluggable.php is loaded - Not prematurely load pluggable.php so plugins can still overwrite functions
#7
@
2 years ago
- Keywords has-testing-info added
Thanks for the patch @oakesjosh!
The alternative would be to manually load pluggable.php
instead of skipping the cache call. However, that would end up preventing any plugins loaded after the offending plugin from overriding any pluggable functions.
While not caching these requests isn't ideal, I think it's better than potentially breaking pluggable.php
. We could consider adding a _doing_it_wrong
here with an indication to wait until plugins_loaded
before making any queries as well.
Cc: @peterwilsoncc, @spacedmonkey.
I don't think this is unit testable, since pluggable.php
will have already been loaded by the test bootstrap. However, to test manually, create a plugin with the following code.
<?php /* * Plugin Name: Test Plugin */ if ( isset( $_GET['test_query'] ) ) { $users = get_users(); wp_die( sprintf( '%d users', count( $users ) ), 'Queried users', array( 'response' => 200 ) ); }
If you visit https://yoursite.com?test_query
, you should see the number of users successfully queried on a WP Die screen. Otherwise, you'll see a fatal error.
This ticket was mentioned in PR #3557 on WordPress/wordpress-develop by @spacedmonkey.
2 years ago
#8
Trac ticket: https://core.trac.wordpress.org/ticket/56952
#10
@
2 years ago
It is worth noting that cache_users
has been called in this class as early as 3.1.
2 years ago
#12
Would this break if a plugin that defines cache_users()
without a function_exists()
check was loaded after the plugin that called get_users()
?
@TimothyBlynJacobs commented on PR #3557:
2 years ago
#13
Yes, though I think that is slightly less of a concern since that can always happen if another plugin overrides a pluggable function.
I don't think this approach works because it will prevent any other plugins that are loaded after the offending plugin from overriding any other pluggable functions.
This ticket was mentioned in Slack in #core by jeffpaul. View the logs.
2 years ago
#16
follow-up:
↓ 17
@
2 years ago
@dd32, @SergeyBiryukov I’d love your opinions about implementing a doing it wrong notice here. I think plugins ideally wouldn’t be doing user queries before plugins_loaded
even prior to the change in 6.1. For instance, plugins also wouldn’t get an opportunity to register necessary filters.
However, I could see MU-Plugins needing to make early queries anyways. So as much as I think it’s “correct” for plugins to wait, I’m not sure we can get away with the notice here. It may just have to be a documentation note.
#17
in reply to:
↑ 16
@
2 years ago
Replying to TimothyBlynJacobs:
I’d love your opinions about implementing a doing it wrong notice here. I think plugins ideally wouldn’t be doing user queries before
plugins_loaded
even prior to the change in 6.1. For instance, plugins also wouldn’t get an opportunity to register necessary filters.
However, I could see MU-Plugins needing to make early queries anyways.
Hmm, MU-plugins is a good point. Still, I strongly agree with not running anything before plugins_loaded
.
Only a few things happen between muplugins_loaded
and plugins_loaded
:
- Cookie and SSL constants are defined.
- Initial post types and taxonomies are created.
- Default theme directory root is registered.
- Recovery mode is initialized (for single sites).
- Active plugins are loaded.
- Pluggable functions are loaded.
So I would say that even for a MU-plugin, it should be recommended to wait until plugins_loaded
before runnning any queries.
@spacedmonkey commented on PR #3557:
2 years ago
#18
Looks good to commit.
@TimothyBlynJacobs commented on PR #3557:
2 years ago
#20
Will commit shortly.
#23
@
2 years ago
- Keywords fixed-major added
- Resolution fixed deleted
- Status changed from closed to reopened
Reopening for backport.
#25
@
2 years ago
I have the bug but after applying the patch, I still have:
[Wed Nov 09 22:35:15.833980 2022] [php7:error] [pid 933177] [client 2a01:e0a:824:3ae0:ade:a428:3e00:8342:40936] PHP Fatal error: Uncaught Error: Call to undefined function wp_cache_get() in /home/Web/Azurseisme/volcanspro/wp-includes/option.php:165\nStack trace:\n#0 /home/Web/Azurseisme/volcanspro/wp-includes/l10n.php(63): get_option()\n#1 /home/Web/Azurseisme/volcanspro/wp-includes/l10n.php(139): get_locale()\n#2 /home/Web/Azurseisme/volcanspro/wp-includes/l10n.php(766): determine_locale()\n#3 /home/Web/Azurseisme/volcanspro/wp-includes/load.php(1395): load_textdomain()\n#4 /home/Web/Azurseisme/volcanspro/wp-includes/class-wpdb.php(1198): wp_load_translations_early()\n#5 /home/Web/Azurseisme/volcanspro/wp-includes/class-wpdb.php(1858): wpdb->select()\n#6 /home/Web/Azurseisme/volcanspro/wp-includes/class-wpdb.php(734): wpdb->db_connect()\n#7 /home/Web/Azurseisme/volcanspro/wp-includes/load.php(562): wpdb->__construct()\n#8 /home/Web/Azurseisme/volcanspro/wp-settings.php(124): require_wp_db()\n#9 /home/Web/Azurseisme/volcanspro/wp-config.php(89): require_once('/home/Web/Azurs...')\n#10 /home/Web/Azurseisme/volcanspro/wp-load.php(50): require_once(' in /home/Web/Azurseisme/volcanspro/wp-includes/option.php on line 165, referer: https://volcanspro.azurseisme.com/les-galapagos/ [Wed Nov 09 22:35:15.842924 2022] [php7:error] [pid 933177] [client 2a01:e0a:824:3ae0:ade:a428:3e00:8342:40936] PHP Fatal error: Uncaught Error: Call to a member function set() on null in /home/Web/Azurseisme/volcanspro/wp-includes/l10n.php:784\nStack trace:\n#0 /home/Web/Azurseisme/volcanspro/wp-includes/l10n.php(872): load_textdomain()\n#1 /home/Web/Azurseisme/volcanspro/wp-includes/class-wp-fatal-error-handler.php(47): load_default_textdomain()\n#2 [internal function]: WP_Fatal_Error_Handler->handle()\n#3 {main}\n thrown in /home/Web/Azurseisme/volcanspro/wp-includes/l10n.php on line 784, referer: https://volcanspro.azurseisme.com/les-galapagos/
Hi @carazo ,
I could not reproduce the issue, it works fine for me even when I invoke
get_users()
without passing any argument.Regarding Line 843 in file wp-includes/class-wp-user-query.php: cache_users( $this->results );
The said function
cache_users()
is located in wp-includes/pluggable.php at Line 125.I am not sure about you setup, but if possible, please deactivate all plugins and switch back to WordPress default theme. If the issue still persists, please feel free to reopen the ticket.