This long comment about validate_settings() for the WordPress Settings API, deserved posting. `validate_settings` is the `$sanitize_callback` denoted in our register_setting() call.


Thank you again Aliso for the options class you generously provided months ago. I’ve recently revised it further for my TYPO3 Importer for WordPress. Some of the changes include fuller validation with error reporting, localization, options updating and denoting fields as required.

Of note, I sanitized my code a little below trying to prevent confusion about naming and relation to the original options class. Link to full code provided at bottom.

Easy stuff first, options updating. I found myself wanting to update values outside of the class and this is a quick way to do so.

function update_my_options( $option, $value = null ) {
	$options					= get_option( 'my_options' );

	if ( ! is_array( $options ) ) {
		$options				= array();
	}

	$options[$option]			= $value;
	update_option( 'my_options', $options );
}

Another mostly easy one, but takes more effort is localization. In the __construct() method, add the following line.

		load_plugin_textdomain( 'my-plugin-name', false, '/my-plugin-name/languages/' );

Then refer to http://codex.wordpress.org/I18n_for_WordPress_Developers#I18n_for_theme_and_plugin_developers for adding text domains and creating the POT files in the languages directory.

I was needing to make sure that certain settings were set, validated, do some action or pass error messages along. The place I’ve learned to do so, is in the validate_settings() method.

First, ensure integer value items are integers.

		if ( '' != $input['import_limit'] ) {
			$input['import_limit']	= intval( $input['import_limit'] );
		}

Second, make sure an option is given and is valid. In my case, is the originating TYPO3 website URL given and is that URL a TYPO3 website. Within, this code, we use the add_settings_error() function to send errors back to the user on submit. add_settings_error() is a flash message which replaces the “Settings saved” text.

		if ( '' == $input['typo3_url'] ) {
			add_settings_error( 'typo3-options', 'typo3_url', __('Website URL is required', 'typo3-plugin-name') );
		} else {
			$typo3_url			= $input['typo3_url'];
			// append / if needed and save to options
			$typo3_url	= preg_replace('#(/{0,})?$#', '/',  $typo3_url);
			// silly // fix, above regex no matter what doesn't seem to work on 
			// this
			$typo3_url	= preg_replace('#//$#', '/',  $typo3_url);
			// Store details for later
			$input['typo3_url']	= $typo3_url;

			// check for typo3_url validity & reachability
			if ( ! $this->_is_typo3_website( $typo3_url ) ) {
				add_settings_error( 'typo3-options', 'typo3_url', __( "TYPO3 site not found at given Website URL", 'typo3-plugin-name' ) );
			}
		}

I couldn’t ever really makes heads or tails of the API guidelines text about the parameters for add_settings_error() at http://codex.wordpress.org/Function_Reference/add_settings_error. So I figured on my standard of add_settings_error( plugin-name, input-field-name, __(message text), ‘error’ or ‘updated’).

Lastly, in case of a bad import or wanting to clear out certain parts of recently imported TYPO3 news, I put my delete actions in validate_settings().

		if ( isset( $input['delete'] ) && $input['delete'] ) {
			switch ( $input['delete'] ) {
				case 'imports' :
					$this->delete_import();
					break;

				case 'comments' :
					$this->delete_comments();
					break;

				case 'attachments' :
					$this->delete_attachments();
					break;
			}

			unset( $input['delete'] );
			return $input;
		}

Notice that in above, I unset the delete input or else, the setting would actually be saved.

In get_settings(), delete is a radio fieldset.

		$this->settings['delete'] = array(
			'section' => 'reset',
			'title'   => __( 'Delete...', 'my-plugin-name'),
			'type'    => 'radio',
			'std'     => '',
			'choices' => array(
				'imports'		=> __( 'Prior imports', 'my-plugin-name') . ': ' . $desc_imports,
				'comments'		=> __( 'Imported comments', 'my-plugin-name') . ': ' . $desc_comments,
				'attachments'	=> __( 'Unattached media', 'my-plugin-name') . ': ' . $desc_attachments
			)
		);

Lastly, since I’m modifying values in validate_settings(), I return input, instead of false at method close.

		return $input;

The TYPO3 Importer is in SVN at WordPress. You can check the code at http://plugins.svn.wordpress.org/typo3-importer/trunk/. In particular, the options class is http://plugins.svn.wordpress.org/typo3-importer/trunk/class.options.php.

TYPO3 Importer at WordPress.