2

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.

6
  • 2
    The option isn't getting saved because the input name has to be aa_myoption (matches the 2nd parameter for register_setting()) or in the array notation like aa_myoption[my_field]. – Sally CJ Apr 9 '20 at 0:17
  • I get the following error: Warning: Illegal string offset 'my_field'. I use it like this: <?php $options = get_option( 'aa_myoption' ); ?> <input id="field-id" type="radio" name="aa_myoption[my_field]" value="myvalue" <?php checked( $options['my_field'], 'myvalue', true ); ?>> – Arg Geo Apr 9 '20 at 9:17
  • I fixed the error by doing this (don't know if this is the right way - is it?): <?php $options = get_option( 'aa_myoption' ); $the_option = $options['my_field']; ?> <input id="field-id" type="radio" name="aa_myoption[my_field]" value="myvalue" <?php checked( $the_option, 'myvalue', true ); ?>> however settings are still not saved. – Arg Geo Apr 9 '20 at 9:37
  • Seems weird but it worked after turning this --> <?php $options = get_option('aa_myoption'); $the_option = $options['my_field']; ?> into this --> <?php $options = get_option('aa_myoption')['my_field']; ?> Could you explain to me why is this happening? I left my previous comments so you can see the process. Thank you very much for your help. – Arg Geo Apr 9 '20 at 9:44
  • It could be because you already saved the option, so $options has the my_field item. Anyway, I hope the answer helps? :) – Sally CJ Apr 9 '20 at 10:12
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. :)

5
  • 1
    Unfortunately, passing an empty array as a default value never crossed my mind, this is really nice however I do not get why type casting is needed since the default value is indeed an array. Isn't PHP a "loose" language? I mean, I would totally understand if we were talking about C. Is it because the option may exist before? In addition, I have problem understanding why passing an empty string in $my_field (inside the array previously declared). – Arg Geo Apr 9 '20 at 10:22
  • Does the "Update" part help, or am I misunderstanding you? :) – Sally CJ Apr 9 '20 at 10:40
  • 1
    You helped me a lot Sally but I still do not get why type casting is needed however I wouldn't like to bother you any more. :) – Arg Geo Apr 9 '20 at 11:00
  • I revised the answer again, but just the additional note #2. I hope that's OK & all the best. :) – Sally CJ Apr 10 '20 at 2:54
  • 1
    It is great! Thanks a ton, you are awesome!! – Arg Geo Apr 10 '20 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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