Having an issue with my plugin updating the htaccess file. The code I used to do that is:
insert_with_markers($htaccess_file, $marker, $lines);
The parameters used in that function have been previously defined properly. There error message is:
Uncaught Error: Call to a member function switch_to_locale() on null
in /home2/path/to/site/fstraptest/wp-includes/l10n.php:1582
I tried ensuring that various functions used by switch_to_locale() are loaded:
if (! function_exists('get_home_path'))
{include_once(ABSPATH . 'wp-admin/includes/file.php');}
if (! function_exists('insert_with_markers'))
{include_once(ABSPATH . 'wp-admin/includes/misc.php');}
if (! function_exists('switch_to_locale'))
{
include_once(ABSPATH . 'wp-admin/includes/l10n.php');
include_once(ABSPATH . 'wp-includes/class-wp-locale-switcher.php');
}
if (! function_exists('got_mod_rewrite'))
{include_once(ABSPATH . 'wp-admin/includes/misc.php');}
if (! function_exists('is_multisite'))
{include_once(ABSPATH . 'wp-admin/includes/load.php');}
But that didn’t solve the issue.
This is with WP 5.3, PHP 7.3.11 . Similar code has worked before; this may have started with WP 5.3, but not sure.
The googles have not helped with this error. The language for the site is “en-US”. The plugin does not have any language files. Theme has been changed to “Twenty-Thirteen”; error also occurs in other themes, so does not appear theme-dependent.
Additional Code
At the top of the plugin file, this code initializes the settings
add_action( 'admin_init', 'CWPSO_settings_init' ); // does register_setting, add_settings_section add_settings_field, etc
The CWPSO_settings_init()
does the register thing, then there are a bunch of add_settings_field()
to set up the options. All of those look similar to this:
add_settings_field(
'CWPSO_protect_config_file', // field name
__( '', 'CWPSO_namespace' ), // message before field (not used)
'CWPSO_protect_config_file_render', // render function
'pluginPage', // plugin page name
'CWPSO_pluginPage_section' // plugin section name
);
This code sanitizes that input field:
if (isset($_POST['CWPSO_protect_config_file'])) {
$new_input['CWPSO_protect_config_file'] = "1";} else { $new_input['CWPSO_protect_config_file'] = "0";}
This code sets up an array of things that might happen to the htaccess file
if (($options['CWPSO_protect_config_file']) and ($_GET['page'] == 'cellarweb_private_function')) {
$change_htaccess[] = 'CWPSO_protect_config_file';
}
This code checks the previous htaccess array, and builds the statements to put in the htaccess
if (in_array('CWPSO_protect_config_file', $change_htaccess) ) {
$lines[] = ' # protect wp-config.php file from direct access';
$lines[] = ' <files wp-config.php>';
$lines[] = ' order allow,deny';
$lines[] = ' deny from all';
$lines[] = ' </files>';
}
This code does the actual htaccess file modification ($marker has been previously set)
$success = insert_with_markers($htaccess_file, $marker, $lines);
And that insert_with_markers()
line causes the error. Note that all of the settings that the plugin uses/creates/save work properly. If I comment out the insert_with_markers()
line, the plugin settings display/save properly.
2 Answers
From your comment:
Those
htaccess
changes don’t happen as a result of anadd_action
.
Perhaps they should?
Yes, they should.
And here’s why
insert_with_markers()
calls switch_to_locale()
which uses $GLOBALS['wp_locale_switcher']
(or $wp_locale_switcher
) which is initialized in wp-settings.php
, but only after WordPress runs the setup_theme
hook.
And looking at the error in question and line #1582 in wp-includes/l10n.php
which is return $wp_locale_switcher->switch_to_locale( $locale );
, that error occurred most likely because the global variable $wp_locale_switcher
has not yet been defined or initialized. Which indicates that you called insert_with_markers()
too early.
So if you want to use insert_with_markers()
, make sure you use the proper hook; for example, load-{$page_hook}
or update_option_{$option}
:
// Example 1:
add_action( 'admin_menu', function () {
$hookname = add_menu_page( ... );
add_action( 'load-' . $hookname, function () {
// Call insert_with_markers()
} );
} );
// Example 2:
add_action( 'update_option_my_field', function ( $old_value, $value ) {
// Call insert_with_markers()
}, 10, 2 );
Both tried & tested working on WordPress 5.2.4 and 5.3.
But it’s also possible there’s a plugin or custom code which is messing with $wp_locale_switcher
, so if using a hook later than setup_theme
doesn’t work for you, you can try deactivating plugins..