I’ve been steadily improving the Options Framework plugin these last several weeks and there’s several nice changes in this 0.6 release. The biggest new feature is sanitization filters and better validation, but there’s also a slew of other less noticeable code improvements.
Unfortunately, a couple things that worked in previous versions will break with this release unless theme code is updated. I debated these changes quite a bit but decided it was best to do this while the plugin is still relatively young and would affect the least amount of people.
Validation Filters
Validation filters are the most exciting update in the Options Framework. Not only is there better sanitization (read security), it’s also now possible to change the default validation on any input without hacking the plugin directly.
Several users had mentioned that they wanted to enter some html in the textareas. I updated this so $allowedtags can be used. But if you wanted a different sanitization method, the default can now be removed and a new one added in via your themes functions. (Edit: $allowedposttags might be used soon instead)
Since, “embed” is not one of the $allowedtags- here’s how you could remove the default santization from a text area and allow “embed” to be used:
/*
* This is an example of how to override a default filter
* for 'textarea' sanitization and use a different one.
*/
add_action('admin_init','optionscheck_change_santiziation', 100);
function optionscheck_change_santiziation() {
remove_filter( 'of_sanitize_textarea', 'of_sanitize_textarea' );
add_filter( 'of_sanitize_textarea', 'of_sanitize_textarea_custom' );
}
function of_sanitize_textarea_custom($input) {
global $allowedtags;
$of_custom_allowedtags["embed"] = array(
"src" => array(),
"type" => array(),
"allowfullscreen" => array(),
"allowscriptaccess" => array(),
"height" => array(),
"width" => array()
);
$of_custom_allowedtags = array_merge($of_custom_allowedtags, $allowedtags);
$output = wp_kses( $input, $of_custom_allowedtags);
return $output;
}
Allow Script and Embed Tags
A lot of folks have been asking how to include all the $allowedpsttags in addition to script and embed tags. Here’s how you would do it (hat tip Jake Caputo):
/*
* This is an example of how to override a default filter
* for 'textarea' sanitization and $allowedposttags + embed and script.
*/
add_action('admin_init','optionscheck_change_santiziation', 100);
function optionscheck_change_santiziation() {
remove_filter( 'of_sanitize_textarea', 'of_sanitize_textarea' );
add_filter( 'of_sanitize_textarea', 'custom_sanitize_textarea' );
}
function custom_sanitize_textarea($input) {
global $allowedposttags;
$custom_allowedtags["embed"] = array(
"src" => array(),
"type" => array(),
"allowfullscreen" => array(),
"allowscriptaccess" => array(),
"height" => array(),
"width" => array()
);
$custom_allowedtags["script"] = array();
$custom_allowedtags = array_merge($custom_allowedtags, $allowedposttags);
$output = wp_kses( $input, $custom_allowedtags);
return $output;
}
Checkbox Code Has Changed
The most noticeable change in version 0.6 is how checkbox data is stored. The reason it’s the most noticeable is because it’s the one most likely to break a current implementation. Instead of storing checkbox data as “true” or “false”, I’ve changed it to “1” or “0”, which is how WordPress itself stores checkbox values and much smarter way to do it. I’ve written about this more in another post called “Checkboxes and Booleans”.
If you currently are using checkboxes in your theme, you should update options.php to use a default value of “0” or “1”. You should also update how the theme reads checkbox data to something like:
if ( of_get_option('checkbox_option', "0") ) {
do_action();
}
Helper Function Returns Boolean False by Default
Instead of having the helper function of_get_option return the string “false” by default, I’ve updated it to return the boolean false (thanks so a suggestion from @sawyerh). Again, there’s more about this in my post on booleans. This should just make it easier to check if options are saved in the database. This change isn’t likely to break something if it isn’t updated, but the new code for your theme should look like this:
if ( !function_exists( 'of_get_option' ) ) {
function of_get_option($name, $default = false) {
$optionsframework_settings = get_option('optionsframework');
// Gets the unique option id
$option_name = $optionsframework_settings['id'];
if ( get_option($option_name) ) {
$options = get_option($option_name);
}
if ( !empty($options[$name]) ) {
return $options[$name];
} else {
return $default;
}
}
}
Better Handling of Option Arrays
I updated the code for how arrays of options (like multicheckbox, background, and typography) are processed and stored. I don’t think should affect current users- but it’s something to keep an eye on. The new code allows the options to be stored directly into the array rather than having an additional step in the validation to process it.
Better Display of Messages
For anyone who dug into the code of 0.5, you probably saw my very awkward way of displaying the “Options Reset” and “Options Saved” messages. I had an option in the database for saving the message which was set when the form was submitted and then later cleared after the message was displayed.
By digging through WordPress core I found a more elegant way to do it. At the top of the options page I now use settings_errors(), which automatically displays any messages.
The messages are set in optionsframework_validate() as it processes the form. So, the reset message it now set like so:
// If the reset button was clicked
if (!empty($_POST['reset'])) {
// If options are deleted sucessfully update the error message
if (delete_option($option_name) ) {
add_settings_error('options-framework', 'restore_defaults', __('Default options restored.'), 'updated fade');
}
}
Thanks and Credits
I owe a big thanks to Michael Fields for this release. He advised me on how to implement the validation filters and did a thorough code review which caught many of the html escaping errors. If you need a really solid WordPress developer to check your code, I’d highly recommend him.
I was only able to have a code review done thanks to several generous donations. Having cash to spend on a third party code check was extremely helpful, made the plugin much stronger, and was well spent! If you use the plugin and can contribute, a PayPal donation will make my day.
And finally, several people have been helping out with testing and development on GitHub. I really appreciate it! I’m probably leaving someone out, but big thanks to @mantone, @rejithomas, @sawyerh, @samargulies, @mfields, @adampickeringq, @djevrek, @utkarshkukreti, @celtic7, @helgatheviking, @johnraz, @jmilone, @thumbnet, and @pastorjack.
Update: Version 0.6 has been released