Making your broken Plugin work again with WordPress 2.8.1

WordPress 2.8.1 contains changes to improve the security of plugins by ensuring that only correctly registered plugin pages can be accessed as well as only showing the link to the page to users who have the capability required in the add_x_page call.

This change has broken a number of plugins which were adding there menus on the wrong action hook bypassing some capability checks.

The correct hook to use, as documented in the codex, is admin_menu. However, some plugins have successfully in the past been using admin_init but this meant that they bypassed some of the capability checking that WordPress does to help limit access to plugins pages.

This capability checking is there to help limit access to plugin added pages but plugins must always use current_user_can() to check the capability they require to ensure they prevent access to incapable users.

The code to look for in your plugins is something like this:

add_action('admin_init', 'my_plugin_menu');

function my_plugin_menu() {
  add_options_page('My Plugin Options', 'My Plugin', 'manage_options', 'your-unique-identifier', 'my_plugin_options');
}

Which should be:

add_action('admin_menu', 'my_plugin_menu');

function my_plugin_menu() {
  add_options_page('My Plugin Options', 'My Plugin', 'manage_options', 'your-unique-identifier', 'my_plugin_options');
}

And don't forget while checking your plugin for this issue go and check to make sure you use current_user_can() to check user capabilities before allowing them to access your plugin page functionality.

16 thoughts on “Making your broken Plugin work again with WordPress 2.8.1

  1. Hi Peter,

    Can you clarify why exactly the plugin would break, or what is it that has changed that causes the breaking?

    Also, what is the solution to cross compatible code?

    1. @Ajay: The changes that were made were done to ensure that WordPress would only load plugin admin pages when requested by a url if they had been correctly registered and the current user was capable of using them.
      Plugins are breaking because they were incorrectly adding menu pages after the admin_menu hook had fired (for example as in the example above on the admin_init hook.
      The solution to code that works before the change and after the change is to add your menus on the admin_menu action (this has always been the recommended way).
      A large majority of plugins were not broken by this change!

  2. I already have add_action(‘admin_menu’, ‘FUNCTION’); for my main settings page. However, there’s a plugin page which is not a menu link (but an inside plugin page which is referenced when the plugin settings are saved). This page still displays the error. Even tried if ( current_user_can(‘manage_options’) ), but didnt work well. How to fix this?

    1. You cannot just link to pages that are not registered as this would make it easy to load up files which should not be loaded so you have two choices to fix your plugin.

      You can use the admin_action_my_action, admin_post_my_action, or wp_ajax_my_action actions to process your form submissions by setting the form action to admin.php?action=my_action, admin-post.php?action=my_action or admin-ajax.php?action=my_action respectively.

      You can post back to your main admin page and handle the post in the function that outputs the normal page form.

  3. I just came across a plugin that was using the admin_head hook to set up the options page.

    In WP 2.8.1 the plugin’s options page would just display a “You do not have sufficient permissions to access this page.” message.

    In WPMU 2.8.1, the plugin’s options page would simply redirect to the main dashboard page.

    I had to change the plugin to use the admin_menu hook instead.

Comments are closed.