More than a few people have contacted me after seeing this message. It usually appears after upgrading to WordPress version 3 or above, when accessing a plugin’s Dashboard menu.
This article isn’t an exhaustive treatment of this issue, but if you’re a developer you’ll at least walk away with an idea of what needs to be fixed in your plugin or theme options menus.
The cause of the “You Do Not Have Sufficient Permissions to Access This Page” error message
The common cause appears to be plugins that use an older method of generating menu and submenu items. Those are the links in your Dashboard’s menu column that appear when you activate a plugin.
When a plugin is activated, certain values are stored in the options table, one of them being a sanitized, shortened version of the plugin name. Later versions of WordPress use slightly different functions for doing this than previous versions. This is where the weirdness starts, and where some plugin developers drop the ball in their testing – previous installs of the plugin will throw errors on upgrading WordPress. Plugins installed after upgrading will be fine, with no errors.
Here is how a main menu item is generated:
add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position );
And a sub-menu item:
add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function);
There are two stumbling blocks here: the $capability and $menu_slug attributes.
First, the $menu_slug. The following is from the Adding Administration Menus page of the WordPress Codex:
The slug name to refer to this menu by (should be unique for this menu). Prior to Version 3.0 this was called the file (or handle) parameter. If the function parameter is omitted, the menu_slug should be the PHP file that handles the display of the menu page content.
Prior to Version 3.0, the value in the menu_slug attribute was used ‘as-is’, no sanitization was performed. This value populates the $_registered_pages[$hookname] value in wp-admin/includes/plugins.php. Here’s where the problem comes in: this is the value that is stored in the options table, including space characters.
Beginning in Version 3.0, space characters in $menu_slug are stripped before storage. Hence, a menu_slug with the value “My Plugin Slug” is stored as “MyPluginSlug”. Prior to 3.0, they were stored as they were passed, spaces and all.
The problem comes when the stored value is compared with the passed value in the add_menu_page and add_submenu_page calls. The new routine strips space characters from the value passed to the function, then compares against the options table entry. Surprise! They don’t match. “MyPluginSlug” <> “My Plugin Slug”.
The $capability attribute:
The capability required for this menu to be displayed to the user. User levels are deprecated and should not be used here!
This is a little easier to fix, as WordPress translates the old number-based user_level value to the new capability value. However, it’s problematic to rely on this conversion as no one knows how long it will be there.