OOP Plugin and Menu – Call to undefined function register_setting()

WordPress documentation seems spotty on object-oriented code. I’m setting up a few plugins and the first should register settings and a menu page. It’s throwing “undefined” for the register_setting() or add_settings_field() calls. Should these go elsewhere?

I’m not seeing the admin settings page get created either? Thanks for any help.

<?php
//$c = new mySettings();
class mySettings {

    public function __construct() {
        $this->add_hooks();
        $this->register_settings();
    }
    public function add_hooks() {
        add_action('admin_menu', array($this, 'admin_menu'));
        add_action('admin_init', array($this, 'register_settings'));
    }
    public function register_settings() {
        //exit('register_settings'. microtime());
        register_setting('mySettings', 'mySettings', null);
        add_settings_field('myUrl', 'API URL', array($this, 'myUrl_callback'), 'my');
        add_settings_field('myOauthUrl', 'API Host', array($this, 'myOauthUrl_callback'), 'my');
        add_settings_field('myClientId', 'API Client Id', array($this, 'myClientId_callback'), 'my');
        add_settings_field('mySharedSecret', 'API Shared Secret', array($this, 'mySharedSecret_callback'), 'my');
    }
    public function admin_menu() {
        exit('admin_menu'. mircotime());
        add_options_page('my API Settings', 'my Settings', 'manage_options', 'my-my', array($this, 'settings_page'));
    }
    public function settings_page() {
        if (!current_user_can('manage_options')) {
            wp_die(__('You do not have sufficient permissions to access this page.'));
        }
        print '<h2>my API Settings</h2><form action="options.php" method="post">';
        print settings_fields('mySettings');
        print do_settings_sections('mySettings_selections');
        print submit_button() .'</form>';
    }
    public function myUrl_callback() {
        $options = get_option('mySettings');
        $option = isset($options['myUrl']) ? $options['myUrl'] : '';
        print '<input id="myUrl" name="mySettings[myUrl]" type="text" value="' . $option . '" />';
    }

}

Related posts

Leave a Reply

1 comment

  1. They are undefined because the functions don’t exist right when plugins (or themes) are loaded — the admin area includes have not happened yet.

    If you want to register settings fields it’s best to hook into admin_init to do so.

    In short, you can fix your class by doing this:

    <?php
    class mySettings {
    
        public function __construct() {
            $this->add_hooks();
        }
    
        // other stuff here
    }
    

    Or this:

    <?php
    //$c = new mySettings();
    class mySettings {
    
        public function __construct() {
            add_action('admin_menu', array($this, 'admin_menu'));
            add_action('admin_init', array($this, 'register_settings'));
        }
    
        // other stuff here
    }
    

    It’s just about the order in which files get included in WordPress. Plugins and themes get loaded early on, before WP even knows where it’s going. That’s why you hook in later (like admin_init or init) to do things like register settings or post types.

    As an aside, I like to structure classes like this:

    <?php
    class WPT26_Awesome
    {
        private static $ins = null;
    
        public static function init()
        {
            // for themes: add_action('after_setup_theme', array(self::instance(), '_setup'));
            add_action('plugins_loaded', array(self::instance(), '_setup'));
        }
    
        public static function instance()
        {
            // create a new object if it doesn't exist.
            is_null(self::$ins) && self::$ins = new self;
            return self::$ins;
        }
    
        public function _setup()
        {
            // other calls to `add_action` here.
        }
    }
    

    Keeps actions/filters out of the constructor which can make things a bit easier to test. You kick everything off with… WPT26_Awesome::init();. Here’s a tutorial on the subject.