add_option_page capability behaving strange

I am trying to build a class to make the job off adding new settings easier. The trouble I am having is that, although I have traced the variable through all of it’s stages, the string ‘manage_options’ doesn’t seem to grant admin the right to amend and option. I keep getting “You do not have sufficient permissions to access this page.” when I try access the new settings page.

Here is a heavily simplified version of the class, the creation function and its action hook.

Read More
class optionObject{
    var $user_level = 'manage_options';

    function add_page() {

        add_options_page(menu_page_title, page_title, $this->user_level, menu_slug, array(&$this, 'do_page'));

    }
    function do_page(){
        //do stuff to display page
    }
}

function test_options(){
    $options = new optionObject();

    add_action('admin_menu', $options->add_page());
}

add_action('admin_init', 'test_options' );

Unedited Version here

Related posts

Leave a Reply

2 comments

  1. admin_init is called after wp-admin/menu.php is included, so the access check has already been executed and the admin_menu action has fired by the time you execute test_options(). Remove the admin_init hook and call test_options() directly, or find another way of structuring your code so that the admin_menu hook is set up correctly.

    You might think it could work because you see the menu option when you are on other pages. This is because the menu is drawn after the page access is checked:

    The menu is drawn in:

    The access check however is done in:

    You see that adding menu items in admin_init is OK to be included in the drawn menu, but too late for the access check. That’s your current situation, and you need to change that by adding the page in the admin_menu hook or earlier.

  2. Jan is spot on with both his answer and comment on the original question..

    Here’s an example of the code working, in it’s most basic form…

    // Either uncomment the constructor function or the line following the creation of the object, simply showing you two working methods
    class test_stuff {
        var $user_level = 'manage_options';
        // PHP4 or PHP5 constructor, you choose - uncomment function line as appropriate
        //function test_stuff() {
        //function __construct() {
        //    add_action( 'admin_menu', array( $this, 'add_new_page' ) );
        //}
        function add_new_page() {
            add_options_page( 'somename', 'somename', $this->user_level, 'somepagename', array( $this, 'display_page' ) );
        }
        function display_page() {
            echo 'Hello World!';
        }
    }
    $test_stuff = new test_stuff();
    //add_action( 'admin_menu', array( $test_stuff, 'add_new_page' ) ); // Alternative to using the constructor function
    

    Hope that helps…