0

I'm using the theme options page from the underscores (_s) theme to build a theme options page and I have a group of check boxes on it. In the example below I've just included 2 for simplicity.

My questions are:

  1. What goes in the checked() function below to keep each check box checked when saved? I have to check each value against the value in the DB correct?
  2. How do I properly sanitize the group of checkboxes? They seem to save to the DB fine, but I know I'm doing something wrong.

Here's each relevant block of code:

// register setting
register_setting(
    'options', // Options group
    'theme_options', // Database option
    'theme_options_validate' // The sanitization callback, see below
);

// add settings field
add_settings_field(
    'post_sharing_networks',
    'Post Sharing Networks To Show',
    'settings_field_post_sharing_networks', // callback below
    'theme_options',
    'general'
);

// set up the array
// more will be added later. 2 shown here for simplicity
function post_sharing_networks() {

    $post_sharing_networks = array(
        'twitter' => array(
            'value' => 'twitter',
            'label' => 'Twitter'
        ),
        'facebook' => array(
            'value' => 'facebook',
            'label' => 'Facebook'
        ),
    );

    return $post_sharing_networks;
}

// callback

function settings_field_post_sharing_networks() {

    $options = get_option( 'theme_options' ); // get array of all the theme options

    $post_sharing_networks = $options['post_sharing_networks']; // this will get array for just the post sharing networks

// eg
    /*
    array (size=2)
  'twitter' => string '1' (length=1)
  'facebook' => string '1' (length=1)
*/

    // builds the checkbox list form the post_sharing_networks() function
    foreach ( post_sharing_networks() as $network ) { ?>    
        <label> 
            <input type="checkbox" value="1" name="theme_options[post_sharing_networks][<?php echo esc_attr( $network['value'] ); ?>]" <?php checked( /* what goes in here for this to work? */ ); ?> />

            <?php echo $network['value']; ?>
        </label>

    <?php }
}


// sanitization callback
function theme_options_validate( $input ) {

    $output = array();

    // how do I properly sanitize the checkbox group?
        // it saves the checkboxes to DB fine currently but I think it can be improved
    $options = get_option( 'theme_options' );

    foreach ( post_sharing_networks() as $network ) {

        if ( isset( $options['post_sharing_networks'] ) )
            $output['post_sharing_networks'] = $input['post_sharing_networks'];

    }

    return apply_filters( 'theme_options_validate', $output, $input );

}   

This is what it looks like when saved into the wp_options table

s:21:"post_sharing_networks";a:2:{s:7:"twitter";s:1:"1";s:8:"facebook";s:1:"1";}

1 Answer 1

1

So checked is fairly simple to understand. It compares the first two values. If they're equal, it spits out checked="checked" if they aren't equal nothing happens.

<?php
$saved = 'on';
$compare = 'on'

// spits out checked="checked"
checked($saved, $compare);

$saved = 'off';
// does nothing
checked($saved, $compare);

How you save check boxes it up to you. Because of the way things get serialized, I like to save "checked" values as on and unchecked values as off.

So to sanitize you'd do something like this:

<?php
function wpse74685_clean_option($dirty)
{
    $clean = array(
        'post_sharing_networks'  => array(),
    );

    // $dirty['post_sharing_networks'] will contain the array of
    // of your checkbox values, so check to make sure its there
    // then loop through.
    if(!empty($dirty['post_sharing_networks']))
    {
        // if the box was checked, the value will be there
        // if not nothing will be there.
        foreach(post_sharing_networks() as $network)
            $clean['post_sharing_networks'][$network['value']] = !empty($dirty['post_sharing_networks'][$network['value']]) ? 'on' : 'off';
    }

    return $clean;
}

Then you calls to checked will be something like this:

<input type="checkbox" value="1" 
       name="theme_options[post_sharing_networks][<?php echo esc_attr($network['value']); ?>]"
       <?php checked($post_sharing_networks[$network['value']], 'on'); ?> />
1
  • Thank you, that made it much clearer for me. I think the problem I was having was that the first parameter in the checked function was not checking against the value in the database, but against it's value from the array that created it.
    – Andrew
    Dec 4, 2012 at 5:20

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.