0

I've created an options page in wordpress with this code:

<?php
add_action( 'admin_menu', 'rtwhc_add_admin_menu' );
add_action( 'admin_init', 'rtwhc_settings_init' );

function rtwhc_add_admin_menu(  ) { 
    add_menu_page( 'Welcome Home CRM API Settings', 'Welcome Home Settings', 'manage_options', 'welcomehome_contact', 'rtwhc_options_page' );
}

function rtwhc_settings_init(  ) { 

    register_setting( 'pluginPage', 'rtwhc_settings' );

    add_settings_section(
        'rtwhc_pluginPage_section', 
        __( 'WelcomeHomeSoftware.com Settings', 'welcome_home' ), 
        'rtwhc_settings_section_callback', 
        'pluginPage'
    );

    add_settings_field( 
        'rtwhc_api_url', 
        __( 'The URL endpoint that you want to query', 'welcome_home' ), 
        'rtwhc_api_url_render', 
        'pluginPage', 
        'rtwhc_pluginPage_section' 
    );

    add_settings_field( 
        'rtwhc_community_id', 
        __( 'Add the community ID you want to use. If you dont change it will use ID 19019 (a test community)', 'welcome_home' ), 
        'rtwhc_community_id_render', 
        'pluginPage', 
        'rtwhc_pluginPage_section' 
    );

    add_settings_field( 
        'rtwhc_api_token', 
        __( 'API token from WelcomeHome', 'welcome_home' ), 
        'rtwhc_api_token_render', 
        'pluginPage', 
        'rtwhc_pluginPage_section' 
    );

    add_settings_field( 
        'rtwhc_debug', 
        __( 'Debug mode. Content and arrays will be added to the errorlog', 'welcome_home' ), 
        'rtwhc_debug_render', 
        'pluginPage', 
        'rtwhc_pluginPage_section' 
    );

}

function rtwhc_api_url_render(  ) { 

    $options = get_option( 'rtwhc_settings' );
    ?>
    <input type='text' name='rtwhc_settings[rtwhc_api_url]' value='<?php echo $options['rtwhc_api_url']; ?>'>
    <?php

}

function rtwhc_community_id_render(  ) { 

    $options = get_option( 'rtwhc_settings' );
    ?>
    <input type='text' name='rtwhc_settings[rtwhc_community_id]' value='<?php echo $options['rtwhc_community_id']; ?>'>
    <?php

}

function rtwhc_api_token_render(  ) { 

    $options = get_option( 'rtwhc_settings' );
    ?>
    <input type='text' name='rtwhc_settings[rtwhc_api_token]' value='<?php echo $options['rtwhc_api_token']; ?>'>
    <?php

}

function rtwhc_debug_render(  ) { 

    $options = get_option( 'rtwhc_settings' );
    ?>
    <input type='checkbox' name='rtwhc_settings[rtwhc_debug]' <?php checked( $options['rtwhc_debug'], 1 ); ?> value='1'>
    <?php

}

function rtwhc_settings_section_callback(  ) { 

    echo __( 'Enter your settings below.', 'welcome_home' );

}

function rtwhc_options_page(  ) { 

        ?>
        <form action='options.php' method='post'>

            <h2>Welcome Home CRM API Settings</h2>
            <p>These are the settings that you will need to make sure that Contact form 7 (you will need it installed) will send to the WelcomeHome CRM upon submission.</p>
            <?php
            settings_fields( 'pluginPage' );
            do_settings_sections( 'pluginPage' );
            submit_button();
            ?>

        </form>
        <?php

}

In my main php file I have set const values: //defaults incase no options are set in the settings page. const WHC_API_URL = 'https://amazingcrm.url'; const WHC_COMMUNITY_ID = '19'; const WHC_ENABLE_DEBUG = true; const WHC_TOKEN = 'muchsecretverysecret';

Then I'm testing for entries based on this code:

function display_options() {
    $welcome_home_options = get_option('rtwhc_settings');

    if (isset($welcome_home_options['rtwhc_api_url'])) {
        $apiurl = 'apiURL is set in options: '.$welcome_home_options['rtwhc_api_url'];
    } else {
        $apiurl = 'apiURL is still from CONST: '.WHC_API_URL;
    }
    if ( isset($welcome_home_options['rtwhc_community_id'])) {
        $communityID = 'Community ID is set in options: '.$welcome_home_options['rtwhc_community_id'];
    } else {
        $communityID = 'Community ID is still from CONST: '.WHC_COMMUNITY_ID;
    }
    if (isset($welcome_home_options['rtwhc_api_token'])) {
        $apitoken = 'Our API token came from options: '.$welcome_home_options['rtwhc_api_token'];
    } else {
        $apitoken = 'Our API token came from CONST: '.WHC_TOKEN;
    }
    if (isset($welcome_home_options['rtwhc_debug'])) {
        $debug = 'Debug mode has been set by options: '.$welcome_home_options['rtwhc_debug'];
    } else {
        $debug = 'Debug Mode is from CONST: '.WHC_ENABLE_DEBUG;
    }


    $output = $apiurl.'<br>'.$communityID.'<br>'.$apitoken.'<br>'.$debug.'<br>';
    return $output;

}
add_shortcode('display-wh-options','display_options');

The problem that I have is when I first run the plugin without setting any content in my new options page, all data is run through the const.

However if I set values in my options page and save, then delete all the options and hit save, the short code function to return my values ('display-wh-options') show this:

apiURL is set in options:

Community ID is set in options:

Our API token came from options:

Debug Mode is from CONST: 1

So for some reason it's return my options values of '' for the 1st three variables. How do i set it so that if the options page fields are deleted after having had a value it still returns my default values (const)?

1 Answer 1

1

Before saving the options the first time get_option( 'rtwhc_settings' ) returns false as the option doesn't exist.

Saving values, deleting them and then saving again causes the value of get_option( 'rtwhc_settings' ) to be an array with the field names as keys, which have empty values.

You can see this, if you var_dump() the option value.

array(3) {
  ["rtwhc_api_url"]=>
  string(0) ""
  ["rtwhc_community_id"]=>
  string(0) ""
  ["rtwhc_api_token"]=>
  string(0) ""
}

rtwhc_debug is missing from the array probably, because it's a checkbox and when it's not checked it doesn't get sent with the $_POST data.

To fix the issue in the shortcode just replace isset() with !empty() checks. The isset() returns true, because the options array has the given key, but it doesn't care, if there's a value (as long as it's not null) for that key or not. With !empty() you check that the key exists and it has some truthy value.

My personal preference is to wrap options calls like this in a helper function, which always returns the data in the expected format and with the necessary default values.

function my_option_values_with_defaults(): array {
    // get options or return empty array instead of false, if option doesn't exist
    $option = get_option('rtwhc_settings', []);

    // get defaults from constants or other source
    $defaults = [
        'rtwhc_api_url' => WHC_API_URL,
        'rtwhc_community_id' => WHC_COMMUNITY_ID,
        'rtwhc_api_token' => WHC_TOKEN,
        'rtwhc_debug' => WHC_ENABLE_DEBUG,
    ];

    // mash found options and defaults together
    $parsed = [];
    foreach ($defaults as $key => $default) {
        $parsed[$key] = ! empty($option[$key]) ? $option[$key] : $default;
    }

    return $parsed;
}

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.