Where to hook register_settings for Settings API when also want to update options outside of Settings API?

Now i’ve thought about it(Mark is me, i use another account when i’m at other locations) all registering a setting does is prepare options.php to accept your incoming form data when a valid nonce is present and also provides a means to hook a sanitization method to the submission of that data. It’s really a convenience thing for plugins, and such..

From the front end of the site it should be perfectly fine to just call update_option and be done with it. It doesn’t need to registered on the front end, because you’re not submitting form data to options.php as you would be for an administration page.

I tried to replicate your problem, but i’ve been unable to, here’s my ugly test code to create a simple registered page that can save options.

class RegisteredSettingsTest {
    private $page;
    private $name="test-option";
    private $options;
    function __construct() {
        add_action( 'admin_init', array( $this, 'admin_init' ) );
        add_action( 'admin_menu', array( $this, 'admin_menu' ) );
    }
    function admin_init() {
        register_setting( 'setting_ref', $this->name, array( $this, 'update_option' ) );
        $this->options = get_option( $this->name );
    }
    function admin_menu() {
        $this->page = add_dashboard_page( 'Test','Test','manage_options','translatable_demo', array( &$this , 'load' ) );
    }
    function update_option( $data ) {
        $clean = array_map( 'absint', $data );
        unset($data);
        return $clean;
    }
    function load() {
        ?>
        <div class="wrap">
            <?php screen_icon('index'); ?>
            <h2>Test</h2>
            <form action="options.php" method="post">
                <?php settings_fields( 'setting_ref' ); ?>
                <p><label for="<?php $this->field_name( 'fieldone') ?>">Field one <input value="<?php $this->get_option( 'fieldone') ?>" name="<?php $this->field_name( 'fieldone') ?>" type="text" /></label></p>
                <p><label for="<?php $this->field_name( 'fieldtwo') ?>">Field two <input value="<?php $this->get_option( 'fieldtwo') ?>" name="<?php $this->field_name( 'fieldtwo') ?>" type="text" /></label></p>
                <p class="submit"><input type="submit" name="Submit" class="button-secondary action" value="Save" /></p>
            </form>
            <!-- Output options data, so we can see how it currently looks -->
            <pre><?php print_r( $this->options ) ?></pre>
        </div>
        <?php
    }
    function field_name( $name, $echo = true ) {
        $name = "{$this->name}[$name]";
        if( $echo )
            echo $name;
        else
            return $name;
    }
    function get_option( $name, $echo = true ) {
        $val="";
        if( is_array( $this->options ) && isset( $this->options[$name] ) )
            $val = $this->options[$name];

        if( $echo )
            echo $val;
        else
            return $val;
    }
}
$r = new RegisteredSettingsTest;

I loaded the page up, entered the values 1 and 2 into the fields and hit Save(which of course works fine and i see the values 1 and 2). I’m using numeric values, because it’s just a simple test.

The most simple front end test i could come up with was to just call update_option inside my single.php(though i could have used any other template file).

update_option( 'test-option', array('fieldone'=>3,'fieldtwo'=>4) );

If there were an issue, i should still see the values 1 and 2 when i load up my test admin page. Unfortunately that’s not the case, the new values, 3 and 4 are shown.

Can you post up the code that you’re using to update the option from the front end? If it’s inside a callback, post the whole function, plus the action/filter it’s hooked onto, please.. 🙂

UPDATE:

Remove the sanitization callback before updating the option.

remove_all_filters( 'sanitize_option_test-option', 10 );

And your values won’t get butchered by the callback function any longer, because it’ll be unhooked.. 🙂

Leave a Comment