0

I use Example #2 from this source:

https://codex.wordpress.org/Creating_Options_Pages

Using a class, it creates settings page. I can access values like this:

$options['id_number']

Or remove database entry for all settings when deleting plugin (it's an array) like this:

delete_option('my_option_name'); // regular site options
delete_site_option('my_option_name'); // multisite options

However this codex example doesn't show how to handle default values. I have seen multiple approaches and read how wrong some of them can be. This said, I would like to display default value on settings page and make it usable by plugin (through saving to database?) if value isn't already stored.

I replaced the following part:

$this->options = get_option( 'my_option_name' );

With:

$this->defaults = array (
            'id_number' => 123,
            'title' => 'my title',
        );

$this->options = get_option($this->'my_option_name', $this->defaults ); 
$this->options = wp_parse_args( $this->options, $this->defaults );

Now values are properly pre-filled on settings page and overridden by settings from db if user saved settings, then deactivated and activated the plugin. Unfortunately these defaults don't exist in db, so I can't use them in plugin code when referencing values like this:

$options['id_number']

What is a good way to make these defaults, perhaps through register_activation_hook( __FILE__, 'myplugin_activate' );, usable in provided Codex example? Full code here:

<?php
class MySettingsPage
{
    /**
     * Holds the values to be used in the fields callbacks
     */
    private $options;

    /**
     * Start up
     */
    public function __construct()
    {
        add_action( 'admin_menu', array( $this, 'add_plugin_page' ) );
        add_action( 'admin_init', array( $this, 'page_init' ) );
    }

    /**
     * Add options page
     */
    public function add_plugin_page()
    {
        // This page will be under "Settings"
        add_options_page(
            'Settings Admin', 
            'My Settings', 
            'manage_options', 
            'my-setting-admin', 
            array( $this, 'create_admin_page' )
        );
    }

    /**
     * Options page callback
     */
    public function create_admin_page()
    {
        // Set class property
        $this->options = get_option( 'my_option_name' );
        ?>
        <div class="wrap">
            <h1>My Settings</h1>
            <form method="post" action="options.php">
            <?php
                // This prints out all hidden setting fields
                settings_fields( 'my_option_group' );
                do_settings_sections( 'my-setting-admin' );
                submit_button();
            ?>
            </form>
        </div>
        <?php
    }

    /**
     * Register and add settings
     */
    public function page_init()
    {        
        register_setting(
            'my_option_group', // Option group
            'my_option_name', // Option name
            array( $this, 'sanitize' ) // Sanitize
        );

        add_settings_section(
            'setting_section_id', // ID
            'My Custom Settings', // Title
            array( $this, 'print_section_info' ), // Callback
            'my-setting-admin' // Page
        );  

        add_settings_field(
            'id_number', // ID
            'ID Number', // Title 
            array( $this, 'id_number_callback' ), // Callback
            'my-setting-admin', // Page
            'setting_section_id' // Section           
        );      

        add_settings_field(
            'title', 
            'Title', 
            array( $this, 'title_callback' ), 
            'my-setting-admin', 
            'setting_section_id'
        );      
    }

    /**
     * Sanitize each setting field as needed
     *
     * @param array $input Contains all settings fields as array keys
     */
    public function sanitize( $input )
    {
        $new_input = array();
        if( isset( $input['id_number'] ) )
            $new_input['id_number'] = absint( $input['id_number'] );

        if( isset( $input['title'] ) )
            $new_input['title'] = sanitize_text_field( $input['title'] );

        return $new_input;
    }

    /** 
     * Print the Section text
     */
    public function print_section_info()
    {
        print 'Enter your settings below:';
    }

    /** 
     * Get the settings option array and print one of its values
     */
    public function id_number_callback()
    {
        printf(
            '<input type="text" id="id_number" name="my_option_name[id_number]" value="%s" />',
            isset( $this->options['id_number'] ) ? esc_attr( $this->options['id_number']) : ''
        );
    }

    /** 
     * Get the settings option array and print one of its values
     */
    public function title_callback()
    {
        printf(
            '<input type="text" id="title" name="my_option_name[title]" value="%s" />',
            isset( $this->options['title'] ) ? esc_attr( $this->options['title']) : ''
        );
    }
}

if( is_admin() )
    $my_settings_page = new MySettingsPage();
2

Instead of saving the default values to the database, you can retrieve them from the class by using a helper method something like the following:

/**
 * Get the option that is saved or the default.
 *
 * @param string $index. The option we want to get.
 */
public function get_settings( $index = false ) {
        $defaults = [ 'id_number' => 123,'title' => 'my title' ];
        $settings = get_option( 'my_option_name', $defaults );
        $settings = wp_parse_args( $settings, $defaults );

        if ( $index && isset( $settings[ $index ] ) ) {
            return $settings[ $index ];
        }

        return $settings;
    }

Hope this helps!

  • Please forgive my php ignorance, I put this function within class, replaced my previous code to fill settings with defaults with $this->options = $this->get_settings(); what works great, but when I want to access particular value within regular function outside class like this: get_settings('id_number'), I'm getting call to undefined function error. What am I doing wrong? Also I had to change this single occurrence of $this->defaults to $defaults to make function work. – Ryszard Jędraszyk Apr 30 at 21:52
  • You will need to call this get_settings on the class instance - i.e $my_settings_page->get_settings('id_number'); – Welcher May 1 at 2:42
  • I created new class instance of settings page within function which executes on page load, then called it as described in comment above and now whole code works perfectly, many thanks! – Ryszard Jędraszyk May 1 at 4:51

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.