Settings API – easiest way of validating checkboxes?

If the setting in question is $setting, and is a checkbox type, you validate it like so:

<?php
$valid_input[$setting] = ( isset( $input[$setting] ) && true == $input[$setting] ? true : false );
?>

In this case, $input is the form data passed to the validation callback, where $input is an array-of-arrays. The validation method is known as whitelisting, where the current settings array is called (in this case, as $valid_input), and each setting in the settings array is only updated if the value in $input[$setting] passes the validation.

With checkboxes, if the checkbox isn’t set, then the setting itself doesn’t get populated in the $input array. So, the first step to validate it is to determine if it’s been set in $input. The second step is to ensure that the value that is set is true (or 'true', or 'on', or whatever it is to which you set the checkbox value in the settings form). If both those conditions are met, return true; otherwise, return false.

See: it’s quite simple, really. 🙂

Edit

Regarding this:

function setting_validate($input) {
   foreach($options as $option) {
     if($option['type'] == "checkbox") { 
        //set it to 1 if sent
     }
   }

   $options = get_option('XX_theme_settings');
   $merged = array_merge($options, $input);  
   return $merged;  
}

…that’s not exactly the way you want to do it. You want to limit the return value to valid options; that is, you want to return, explicitly, the settings that you know you’ve defined. If, somehow, someone can populate $input with additional data – i.e. malicious code – your method would simply pass that additional data right into the database.

Don’t do an array_merge(). Update each $valid_options[$setting] separately/individually, and only ever return $valid_options.

Here’s the process:

  1. Define the currently valid data:

    $valid_input = get_option( 'XX_theme_settings' );
    
  2. Update the currently valid data with $input only if $input passes your validation/sanitization.
  3. Then return the updated, currently valid data.

If the fields are being generated dynamically, then you should also step through them dynamically, in your validation callback. You have this correct, with foreach( $options as $option ).

Putting it all together might look like this:

<?php
function setting_validate( $input ) {
    // Get current setting values
    $valid_options = get_option( 'XX_theme_options' );
    // Get option parameters array
    // Note: XX_theme_get_option_parameters() function
    // should be defined to return the array you've 
    // defined for $options
    $options = XX_theme_get_option_parameters();
    // Now step through the option parameters,
    // and validate each $input[$option]
    foreach( $options as $option ) {
         // If $option['type] is a checkbox
         if( 'checkbox' == $option['type'] ) { 
             // verify that $input[$option] is set
             // and is set with a valid value;
             // if so, set $valid_input[$option] to 1
             $valid_input[$option] = ( isset( $input[$option] && true == $input[$option] ? 1 : 0 );
         }
     }
     // Return the updated $valid_input array
     return $valid_input;
}
?>

Leave a Comment