Themergency fooplugins.com

Store Plugin Settings As Single Option

| 3 Comments

This is day 11 of my WordPress Developer Advent Calendar.

Most WordPress plugins have a settings page where you can turn features on or off etc. But how do you store these settings? The majority of the time you use the built-in functions for saving options:

add_option( 'enable_something', true );

And then you retrieve it:

$enabled = get_option( 'enable_something' );

Now what about a plugin that has dozens and dozens of settings? Well, you end up polluting the options table with just as many entries, all usually prefixed with your plugin name. I don’t like this.

One Option To Rule Them All

Rather combine all your settings into an array and save that single array to the WordPress options table. This function accomplished that:

function save_uber_option($option_name, $key, $value) {
	//first get the option
	$options = get_option( $option_name );
	if ( !$options ) {
		//no options have been saved yet, so add it
		add_option( $option_name, array($key => $value) );
	} else {
		//update the existing option
		$options[$key] = $value;
		update_option( $option_name, $options );
	}
}

A rundown of what this code is doing:

  1. We first get the option.
  2. If the option does not already exist then we add it.
  3. Else, add the key-value to the existing array and update the option.

Now for the retrieval function:

function get_uber_option($option_name, $key, $default = false) {
	$options = get_option( option_name );
	if ( $options ) {
		return (array_key_exists( $key, $options )) ? $options[$key] : $default;
	}
	return $default;
}

A rundown of what this code is doing:

  1. First, get the option.
  2. If it exists and the key exists in the array, extract the value out of the array
  3. If all else fails, return a default value.

And finally, a delete function:

function delete_uber_option($option_name, $key) {
	$options = get_option( $option_name );
	if ( $options ) {
		unset($options[$key]);
		update_option( $option_name, $options );
	}
}

A rundown of what this code is doing:

  1. Again, get the option.
  2. If it exists then remove the key from the array and update the option with the new array.

It Could Be Better

As with most code, It could be improved. You could wrap these functions in a class and pass in the $option_name via the constructor. This also does not cater for multisite. I will be posting this code on Github soon, as part of my plugin base framework. Watch this space!

3 comments
  Livefyre
  • Get Livefyre
  • FAQ
pbaylies
pbaylies

We do all of this in All in One SEO Pack as well; unfortunately it's a bit more complicated because it supports a few other use cases as well, but yes, by all means store all your options as an array (or an object) and check it against an array of defaults, etc.; works great.

chip_bennett
chip_bennett

Even better? Wrap the get_option() call in a wrapper function, and return an array merge of get_option() against a defaults array. Then instead of calling get_option() directly, you call your wrapper function. The biggest benefit with this approach is that the Theme/Plugin never saves anything directly to the database. Settings only get stored if the user goes to the settings page, and hits "save" - and yet the Theme/Plugin still works properly even if the user never does so.


For example:


function pluginslug_default_options() {

  return array( /* build defaults array here */ );

}


function pluginslug_get_options() {

    return array_merge( get_option( 'plugin_slug_options', array() ), pluginslug_default_options() );

}


Then in the template/elsewhere in the Plugin:


$options = pluginslug_get_options();

if ( 'foo' == $options['bar'] ) {

    // do something

}

themergency
themergency moderator

@chip_bennett great tip and thanks for popping round :) 


Providing a defaults array is a great idea and I will def build that into my helper class on git