3

We use the default WordPress register_setting() function to validate theme options. This call, for example:

register_setting( 'options-group', 'option1', 'intval' );

Will validate whether or not $option1 is an integer.

What can I use to pass an array of options to validate each member of the array?

For example:

$options = array(
    'options1' => 4,              // intval
    'options2' => '127.0.0.1',    // IP address
    'options3' => '[email protected]' // Email address
);
2
  • Validating whether or not elements exist in an array isn't really a WordPress question ... it's basic PHP.
    – EAMann
    Commented Jun 21, 2012 at 17:07
  • actually i write a simple example but with callback functions its wp specific question imo.. this is not normal validation question -.- Commented Jun 21, 2012 at 18:01

2 Answers 2

11

What you need to do is build your own data validation function. Ozh wrote a great tutorial about this earlier, but here's the gist of it ...

Assume your options array is called $my_options and it contains three fields, 'text', 'age', and 'isauthorized'.

You would still register it the same way:

register_setting( 'my_setting', 'my_options', 'my_validation_function' );

But you see how we used a custom callback for the third parameter? Now we just need to define that custom function:

function my_validation_function( $input ) {
    // Validate age as an integer
    $input['age'] = intval( $input['age'] );

    // Strip HTML tags from text to make it safe
    $input['text'] = wp_filter_nohtml_kses( $input['text'] );

    // Make sure isauthorized is only true or false (0 or 1)
    $input['isauthorized'] = ( $input['isauthorized'] == 1 ? 1 : 0 );

    return $input;
}

Alternatively

If you want to make your validation functions a bit more flexible, you can use WordPress' built-in filters to avoid having to repeat your code. You still register your validation the same way:

register_setting( 'my_setting', 'my_options', 'my_validation_function' );

But instead of checking each element of your array inside the validation function, you iterate through the array and delegate to filters:

function my_validation_function( $input ) {
    foreach( $input as $key => $value ) {
        $input[$key] = apply_filters( 'my_validation_' . $key, $value );
    }

    return $input
}

Now you can hook in whatever validation logic you need:

add_filter( 'my_validation_age', 'validate_numeric' );
function validate_numeric( $numeric ) {
    return intval( $numeric );
}

add_filter( 'my_validation_text', 'validate_text' );
function validate_text( $text ) {
    return wp_filter_nohtml_kses( $text );
}

add_filter( 'my_validation_isauthorized', 'validate_bool' );
function validate_bool( $bool ) {
    return $bool == 1 ? 1 : 0;
}

If you don't add a filter for one of your options, then the value of the option will remain unchanged. Filters are also the way you want to go with functions that return content, and you can add as many as you want ... or attach your filters to any fields.

Let's say you had two numeric fields in your array - age and numberChildren. Instead of creating an extra validation function that can handle the numberChildren field, you just add it to the filter:

add_filter( 'my_validation_numberChildren', 'validate_numeric' );
3
  • I like this alternate approach, but how would you handle saving checkboxes? They are only POSTed if they are checked, so the foreach that loops over every result will not save an unchecked checkbox.
    – donnapep
    Commented Dec 12, 2015 at 12:57
  • Guys, how is this validation? If an input is wrong nothing should be saved, the user should be presented with the wrong input and a helpful validation message. add_settings_error() is the man! Commented Mar 13, 2016 at 20:04
  • This is not validation but sanitization. However, WordPress has a large share of badly designed or named functions. This one is overloaded both with sanitization and validation. To not update option because of invalid values just return old value. It is also wise to add an usable error using add_settings_error(). Commented Mar 13, 2019 at 5:08
1

It seems "different function usage for each option in array"'s solution is not like in my dream but i think this should work:

register_setting( 'my_setting', 'my_options', 'my_validation_function' );

function my_validation_function( $input ) {
    foreach ($input as $option=>$value){
        do_action('my_validation_'.$option, $option, $value);
    }
    return $input;
}

and then i can use custom functions for each option validation like this:

add_action('my_validation_age', 'my_validation_function_for_age', 10, 2);
function my_validation_function_for_age($option, $value) {
    $input[$option] = intval( $value );
}

add_action('my_validation_text', 'my_validation_function_for_text', 10, 2);
function my_validation_function_for_text($option, $value) {
    $input[$option] = wp_filter_nohtml_kses( $value );
}

add_action('my_validation_isauthorized', 'my_validation_function_for_isauthorized', 10, 2);
function my_validation_function_for_isauthorized($option, $value) {
    $input[$option] = ( $value == 1 ? 1 : 0 );
}

Writing here for future visitors. Accepting EAMann's solution.

1
  • Instead of retaining 2 "correct" answers, I added much of your code as an alternative solution below mine. I also elected to use filters instead of actions since that's really what you should be using to filter content in this fashion.
    – EAMann
    Commented Jun 21, 2012 at 21:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.