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

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.