Custom theme options Radio inputs not saving

Why isn’t the following option getting saved? Have been searching for quite some time and can’t get it to work.

Settings code:

add_settings_section( 'aa_myoption_section', null, null, 'mypage-options' );

add_settings_field(
   'aa_myoption',
   null,
   'aa_myoption_interface',
   'mypage-options',
   'aa_myoption_section',
);
register_setting ( 'myoptions_group', 'aa_myoption' );

aa_myoption_interface function:

$options = get_option( 'aa_myoption' );
echo 'debug: ' . $options;

<input id="first_radio" type="radio" name="radio_group" value="first" <?php checked( $options, 'first', true ); ?>>
<label for="first_radio">First Radio</label>
<input id="second_radio" type="radio" name="radio_group" value="second" <?php checked( $options, 'second', true ); ?>>
<label for="second_radio">Second Radio</label>
<input id="third_radio" type="radio" name="radio_group" value="third" <?php checked( $options, 'third', true ); ?>>
<label for="third_radio">Third Radio</label>

In addition to that I would like to know how is it possible to store an array in aa_myoption and save multiple fields like get_option('aa_myoption')['first_field'], get_option('aa_myoption')['second_field'] and so on. I tried saving text input like this and I got an error saying “Warning: ‘first_field’ illegal string’.

Thanks in advance.

1 Answer
1

Why isn’t the following option getting saved?

Because the database option name (the second parameter for register_setting()) is aa_myoption, hence the input name has to be aa_myoption or in the array notation like aa_myoption[my_field]:

<input name="aa_myoption">           <!-- like this -->
<input name="aa_myoption[my_field]"> <!-- or this -->

Secondly, when you retrieve the option value and when it is an array of settings (like the second <input> above), and as with any other arrays, you should check if an array key exists before attempting to use the value:

<?php
$options = (array) get_option( 'aa_myoption', array() );
$my_field = isset( $options['my_field'] ) ? $options['my_field'] : '';

// Then for example when using checked():
?>
<input name="aa_myoption[my_field]" type="checkbox" value="myvalue"<?php checked( $my_field, 'myvalue' ); ?>>
<?php
// Or you can also use wp_parse_args() to make sure all KEYS are set:
$options = wp_parse_args( get_option( 'aa_myoption', array() ), array(
    'my_field' => '',
) );

// Then for example when using checked():
?>
<input name="aa_myoption[my_field]" type="checkbox" value="myvalue"<?php checked( $options['my_field'], 'myvalue' ); ?>>

Additional notes

  1. $my_field = isset( $options['my_field'] ) ? $options['my_field'] : '';

    The empty string doesn’t necessarily need to be empty, we’re simply assigning a default value to $my_field when the array key/item my_field doesn’t already exist, and you can even use the PHP 7 format — $my_field = $options['my_field'] ?? ''; which does the same thing as the one above. =)

  2. $options = (array) get_option( 'aa_myoption', array() );

    A bit of explanation:

    • I’m telling get_option() to return an empty array if the option does not exist yet, i.e. the database query WHERE option_name="aa_myoption" returned no results.

    • I’m type-casting the value to an array to make sure it’s indeed an array, because WordPress options (both custom and core options like admin_email) can be easily filtered by plugins and your own code.. e.g. via the option_<option name> hook, and it is possible that a plugin (or custom code) returned a non-array value.

      But of course, the best practice is for filter callbacks to always return the proper type of value.

      And I removed the sample test cases from this answer, but you can always check them here. 😉

      Also, I’d likely use the wp_parse_args(), but I’d probably create a my_theme_get_options() function or something like that, which returns an array with options from the database and merged with the default values. 🙂

Leave a Comment