rhubarbgroup / redis-cache

A persistent object cache backend for WordPress powered by Redis. Supports Predis, PhpRedis, Relay, replication, sentinels, clustering and WP-CLI.
https://wordpress.org/plugins/redis-cache/
GNU General Public License v3.0
425 stars 148 forks source link

Resolve uncaught Error #507

Closed tillkruss closed 5 months ago

tillkruss commented 6 months ago
[01-Mar-2024 07:49:57 UTC] PHP Fatal error:  Uncaught Error: Call to a member function get() on null in /home/www/cc.cz/subdomains/www/wp-content/object-cache.php:193
Stack trace:
#0 /home/www/cc.cz/subdomains/www/wp-includes/option.php(599): wp_cache_get()
#1 /home/www/cc.cz/subdomains/www/wp-includes/option.php(164): wp_load_alloptions()
#2 /home/www/cc.cz/subdomains/www/wp-includes/theme.php(319): get_option()
#3 /home/www/cc.cz/subdomains/www/wp-includes/theme.php(332): get_template()
#4 /home/www/cc.cz/subdomains/www/wp-includes/l10n.php(1306): get_template_directory()
#5 /home/www/cc.cz/subdomains/www/wp-includes/l10n.php(1331): _load_textdomain_just_in_time()
#6 /home/www/cc.cz/subdomains/www/wp-includes/l10n.php(185): get_translations_for_domain()
#7 /home/www/cc.cz/subdomains/www/wp-includes/l10n.php(297): translate()
#8 /home/www/cc.cz/subdomains/www/wp-content/object-cache.php(2922): __()
#9 /home/www/cc.cz/subdomains/www/wp-content/object-cache.php(2890): WP_Object_Cache->show_error_and_die()
#10 /home/www/cc.cz/subdomains/www/wp-content/object-cache.php(566): WP_Object_Cache->handle_exception()
#11 /home/www/cc.cz/subdomains/www/wp-content/object-cache.php(256): WP_Object_Cache->__construct()
#12 /home/www/cc.cz/subdomains/www/wp-includes/load.php(856): wp_cache_init()
#13 /home/www/cc.cz/subdomains/www/wp-settings.php(131): wp_start_object_cache()
#14 /home/www/cc.cz/subdomains/www/wp-config.php(114): require_once('...')
#15 /home/www/cc.cz/subdomains/www/wp-load.php(50): require_once('...')
#16 /home/www/cc.cz/subdomains/www/wp-blog-header.php(13): require_once('...')
#17 /home/www/cc.cz/subdomains/www/index.php(17): require('...')
#18 {main}
  thrown in /home/www/cc.cz/subdomains/www/wp-content/object-cache.php on line 193
tillkruss commented 6 months ago

@yatsukhnenko: This commit did not work: 399664183c7f09e05dff12ac8d37cc8fb6b2030d

Instead of the function_exists() call we should call:

if ( ! isset( $l10n_unloaded[ $domain ] ) ) {
   load_plugin_textdomain(...);
}

Can you please test that by throwing an exception in our wp_cache_init()?

tillkruss commented 6 months ago
define ('WPLANG', 'uk_UK');
yatsukhnenko commented 6 months ago

@tillkruss proposed change doesn't solve the issue. Also load_plugin_textdomain requires WP_PLUGIN_DIR which is not defined while wp_cache_init. When I define it load_plugin_textdomain throws similar error Call to a member function get() on null.

tillkruss commented 6 months ago

@tillkruss proposed change doesn't solve the issue. Also load_plugin_textdomain requires WP_PLUGIN_DIR which is not defined while wp_cache_init. When I define it load_plugin_textdomain throws similar error Call to a member function get() on null.

That great that you can reproduce it.

What about calling this right after wp_load_translations_early();:


$domain = 'redis-cache';
$locale = defined( 'WPLANG' ) ? WPLANG : 'en_US';
$mofile = WP_LANG_DIR . '/plugins/' . $domain . '-' . $locale . '.mo';

load_textdomain( $domain, $mofile, $locale );

It might need minor tweaks. But passing locale to the call should just load it.

yatsukhnenko commented 6 months ago

That great that you can reproduce it.

To reproduce issue I have to modify WP source code...

What about calling this right after wp_load_translations_early();:

I'll check this and let you know the result

yatsukhnenko commented 6 months ago

@tillkruss your code snippet works, also there is another possible solution

add_filter( 'pre_wp_load_alloptions', function () {
    return [ 'template' => '', 'stylesheet' => '' ];
} );
tillkruss commented 6 months ago

The filter approach is smart, but let's go with my load_textdomain(), because it's more robust against wp core updates.

yatsukhnenko commented 6 months ago

@tillkruss when there is no .mo file problem still exists, for example for uk_UA lang I see following error

#0 /var/www/html/wp-includes/option.php(599): wp_cache_get('alloptions', 'options', false)
#1 /var/www/html/wp-includes/option.php(164): wp_load_alloptions()
#2 /var/www/html/wp-includes/l10n.php(63): get_option('WPLANG')
#3 /var/www/html/wp-includes/l10n.php(156): get_locale()
#4 /var/www/html/wp-includes/l10n.php(1300): determine_locale()
#5 /var/www/html/wp-includes/l10n.php(1331): _load_textdomain_just_in_time('redis-cache')
#6 /var/www/html/wp-includes/l10n.php(185): get_translations_for_domain('redis-cache')
#7 /var/www/html/wp-includes/l10n.php(297): translate('Error establish...', 'redis-cache')
#8 /var/www/html/wp-content/object-cache.php(2936): __('Error establish...', 'redis-cache')
#9 /var/www/html/wp-content/object-cache.php(2891): WP_Object_Cache->show_error_and_die(Object(Exception))
#10 /var/www/html/wp-content/object-cache.php(504): WP_Object_Cache->handle_exception(Object(Exception))
#11 /var/www/html/wp-content/object-cache.php(256): WP_Object_Cache->__construct(false)
#12 /var/www/html/wp-includes/load.php(856): wp_cache_init()
#13 /var/www/html/wp-settings.php(131): wp_start_object_cache()
#14 /var/www/html/wp-config.php(154): require_once('/var/www/html/w...')
#15 /var/www/html/wp-load.php(50): require_once('/var/www/html/w...')
#16 /var/www/html/wp-blog-header.php(13): require_once('/var/www/html/w...')
#17 /var/www/html/index.php(17): require('/var/www/html/w...')
#18 {main}
  thrown in /var/www/html/wp-content/object-cache.php on line 193
tillkruss commented 6 months ago

@yatsukhnenko Good catch! Can we stack these?

Something like:

  1. Try and load using load_textdomain()
  2. If load_textdomain() returns false (no .mo file?) a. Set WPLANG to a fixed en_US if constant is not defined b. If constant is set apply your add_filter()?

Does that resolve all the various cases?