Trouble Validating Hex Color in WordPress Admin Settings

Ok, I have searched everywhere for this. Google, forums, etc… I’m a PHP newb.

I understand how to validate a color hex code with PHP, but for some reason this isn’t working for me.

This function is the sanitization callback for regester_settings within a custom WordPress admin page.

WordPress options are stored as

$options = array

Example: $options[‘color_1’], $options[‘color_2’], etc…

Everything is working, but I can’t seem to get the validation figured out. Things like <script> or <p> will still save to the database. Any help would be much appreciated! I know this is super simple for most of you.



function jkd_color_sanitize($input) {
	foreach($input as $value) {
		if ( ! preg_match ( '/^#(?:(?:[a-f\\d]{3}){1,2})$/i', $value ) ) {
			die;
		}
		else {
			return $input;
		}
	}
}

[fphp]hexdec[/fphp] will convert a hex string to an integer, though it tolerates bad characters. [fphp]dechex[/fphp] will give the hex expression of a integer. If the user gave you a valid hex string it should pass through the two functions without incident. strtolower is used to give the user a little slack by ignoring case (the output of dechex will always be lower case )


if ( strtolower($string) == dechex(hexdec($string)) ) {
  // valid
} else {
 // invalid
}

Thanks for your help Michael. I tried that out but couldn’t quite get it to do what I wanted. Finally did get it sorted though, after 8+ hours! Ugh!

Here’s the code for any other Newbs who come upon this.

//Theme color sanitization callback
function jkd_color_sanitize($input) {

	$input['color_1'] =  wp_filter_nohtml_kses($input['color_1']);
	$input['color_2'] =  wp_filter_nohtml_kses($input['color_2']);
	$input['color_3'] =  wp_filter_nohtml_kses($input['color_3']);
	$input['color_4'] =  wp_filter_nohtml_kses($input['color_4']);
	$input['color_5'] =  wp_filter_nohtml_kses($input['color_5']);
	$input['color_6'] =  wp_filter_nohtml_kses($input['color_6']);
	$input['color_7'] =  wp_filter_nohtml_kses($input['color_7']);
	
	return $input;
	
}

Thanks everyone! Also, if there is a better way to do this I’m all ears. I couldn’t figure out who to use a foreach loop to accomplish this, though I’m sure it would be cleaner.