For all expert WP Theme devs, when using multiple update_option()
is there a way to test if any of the updates did not work (whether by connection error or by validation) and so it will throw an error? And if there was an error is it possible for all previous update_option()
codes to be disregarded?
Thanks guys!
update_option() returns false if the update fails for any reason. However, it also returns false for when an option is already set to the value you are trying to to update it to.
So, you would be best to first check if the option needs updating or exists using get_option and then if it needs to be updated, update it.
If your option fails your validation test, then just break out of whatever validation function you are using. You could throw a Wp_Error, but that seems too invasive. I tend to use the add_settings_error and display the error to my users that way.
To roll back any of your previous update_option calls would require that you store the previous values in an array, and if then iterate back over them if you need to restore your options.
Generally I use one options table entry to handle things like theme options, or plugin options. Nothing worse than getting a theme that pollutes my options table with a new option for each and every setting.
Edit:
The following is how I handle options validation for my theme options and plugins pages. Its Class based, so you will have to swap out some of the vars if you are using a procedural approach.
public function theme_options_validate( $input ) {
if ($_POST['option_page'] != $this->themename.'_options') {
add_settings_error($this->themename.'_theme_options', 'badadmin', __('<h3><strong>Smack your hands!</strong></h3> - You don\'t appear to be an admin! Nothing was saved.', $this->textDom), 'error');
return $input;
}
if ( empty($_POST) && !wp_verify_nonce($_POST[$this->themename.'_options'],'theme_options_validate') ) {
add_settings_error($this->themename.'_theme_options', 'badadmin', __('<h3><strong>Smack your hands!</strong></h3> - You don\'t appear to be an admin! Nothing was saved.', $this->textDom), 'error');
return $input;
}
//begin validation - first get existing options - if any
$init_themeoptions = get_option( $this->themename.'_theme_options' );
//create an array to store new options in
$newInput = array();
//check to see if the author param has been set
if($input[$this->shortname.'_meta-author'] !== '') {
$newInput[$this->shortname.'_meta-author'] = wp_filter_nohtml_kses( $input[$this->shortname.'_meta-author] );
}else{
add_settings_error($this->themename.'_theme_options', 'emptydata', __('Oops - Author cant be empty'.', $this->textDom), 'error');
}
//finally we see if any errors have been generated
if(get_settings_errors($this->themename.'_theme_options')){
//if there are errors, we return our original theme options if they exist, otherwise we return the input data
//this clause handles the situation where you have no theme options because its your themes first run
if($init_themeoptions != false) {
return $init_themeoptions;
}else{
return $input;
}
}
//if there were no errors we return the sanitized $newInput array and indicate successful save of data using settings error class, but
//we don't use the error attribute, which isnt all that intuitiive
add_settings_error($this->themename.'_theme_options', 'updated', __('<em>Success! </em> '.ucfirst($this->themename).' Theme Options updated!', $this->textDom), 'updated');
return $newInput;
}
To show settings errors in your theme options ui add the following line to where you generate your options form;
settings_errors( $this->themename.'_theme_options' );
And yes, the options table exists already. What I was meaning that instead of generating a new entry into the options table for each of your theme options, you wrap them all up in one option entry. This also makes it easier to validate the options data.