WooCommerce Custom Setting Validation, Sanitization and Escaping

Recently I’ve been working on a light version of my Simple Inventory Sync plugin which I hope you will see soon in the WordPress plugins directory and I faced with a very interesting task.

I needed to create additional settings fields in WooCommerce > Settings > Products and one of the fields should contain an application password for REST API authentication, so obviously I didn’t want that value to be displayed for anyone who can view the settings pages.

So I needed this:

WooCommerce custom settings

And more than that I needed to escape an URL in the “Store URL” fields. So, now let’s dive into this in details.

Please note, that techniques I’m about to describe below can be applied to WooCommerce settings pages only, for regular settings pages there could be a different approach.

Sanitization

I think that’s the easiest part, because WooCommerce provides special filter hooks for that:

Let’s try to sanitize “Store URL” first:

// add_filter( 'woocommerce_admin_settings_sanitize_option_{OPTION NAME}', ...
add_filter( 'woocommerce_admin_settings_sanitize_option_rudr_store_url', 'sanitize_url' );

So we’re just using a default WordPress function sanitize_url() here.

In terms of the application password we need to do the following sanitization – if the value is ending with ****, then we do nothing (or we can also get the previous value from the database and return as a part of sanitization).

Let’s try to do it right now:

// add_filter( 'woocommerce_admin_settings_sanitize_option_{OPTION NAME}', ...
add_filter( 'woocommerce_admin_settings_sanitize_option_rudr_pwd', function( $application_password ) {
	
	if( str_ends_with( $application_password, '****' ) ) {
		return null;
	}
	return $application_password;
	
} );

The same can be done with woocommerce_admin_settings_sanitize_option hook:

add_filter( 'woocommerce_admin_settings_sanitize_option', function( $value, $option, $raw_value ) {
	
	if( 'rudr_pwd' !== $option ) {
		return $value;
	}
	
	if( str_ends_with( $value, '****' ) ) {
		$value = get_option( 'rudr_pwd' );
	}
	
	return $value;
	
}, 10, 3 );

Validation

The best idea that comes to my mind on how to adapt it for our example is to check whether the application password has the appropriate length. Because sometimes users might try to use their account passwords which is wrong, but the application password length is always 19 symbols.

I’ve been thinking for a while which hook we can use for settings validation and it seems like we need to use the same we used for sanitization, just in case the validation don’t go through, we need to add an error.

// Validation part!
if( 19 !== strlen( trim( $value ) ) ) {
	WC_Admin_Settings::add_error( 'This is not an application password.' );
	return null;
}

That simple! No redirection required and no need to use the admin_notices hook.

WooCommerce settings validation error

Escaping

In order to get and print settings values inside fields WooCommerce just uses get_option() WordPress function. So for custom escaping you need to do two things:

// add_filter( 'option_{OPTION NAME}', ...
add_filter( 'option_rudr_pwd', function( $application_password ) {

	if( function_exists( 'get_current_screen' ) && ( $screen = get_current_screen() ) && 'woocommerce_page_wc-settings' === $screen->id ) {
		$application_password = substr_replace( $application_password, '*****', - ( strlen( $application_password ) - 9 ) );
	}

	return $application_password;

} );
Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X