Site icon Hip-Hop Website Design and Development

Unable to get a simple plugin admin page to work

Even though I have years of software development experience, I am new to WP & PHP development, so please bear with me.

After reading through the plugin manual, I started with a WP plugin boiler plate, made all the required field and name changes, added a custom capability, and, as a first real functionality, tried to add a simple admin interface for the plugin like so:

<?php

class Plugin_Name_Admin {

    // some code ommitted, the actual code uses my plugin's name, slugs, and fields

    public function init() {
        add_action('admin_menu', array($this, 'add_plugin_admin_menu'));
    }

    function add_plugin_admin_menu() {
            add_menu_page(
                'Plugin Name',
                'Plugin Menu',
                PLUGIN_USER_CAPABILITY,
                'plugin-name-admin',
                array( $this, 'admin_page' ),
                null,
                1
            );
        }
    
    function admin_page() {
        if ( current_user_can( PLUGIN_USER_CAPABILITY ) ) {
            require_once plugin_dir( __FILE__ ) . 'partials/plugin-name-admin-display.php';
        }
    }
}

The menu shows up for the users that have the assigned capability and the URL looks like http://wp.localhost/wp-admin/admin.php?page=plugin-name-admin but neither an administrator nor another user with the PLUGIN_USER_CAPABILITY can access that page. The error message is "Sorry, you are not allowed to access this page." and the error occurs in wp-admin/includes/plugin.php in the function user_can_access_admin_page where WP checks the following:

        if ( ! isset( $_registered_pages[ $hookname ] ) ) {
            return false;
        }

The hookname it uses is admin_page_plugin-name-admin-admin.

What am I missing?

Also, any pointers on how to properly debug WP code in PhpStorm would be greatly appreciated. So far, I’ve just been muddling around with added error messages.

EDIT: The Plugin_Name_Admin class is instantiated in the boilerplate code’s main class in the define_admin_hooks function, which also adds the hook for the init function:

    private function define_admin_hooks() {

        $plugin_admin = new Plugin_Name_Admin( $this->get_plugin_name(), $this->get_version() );

        $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
        $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );
        $this->loader->add_action( 'admin_init', $plugin_admin, 'init' );

    }

This function is called from the constructor of the main class and uses the boiler plate’s loader approach to create hooks.

As I mention in my answer below, changing the call to add_plugin_admin_menu from a hook for admin_menu to a direct call solved the permission error.

EDIT2: I got PhpStorm to work with XDebug using this write-up.