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:
wp-admin/menu-header.php
on line 169- included in
wp-admin/admin-header.php
on line 143- included from various places, but always after
wp-admin/admin.php
line 132- which is after
admin_init
fires inwp-admin/admin.php
on line 98
- which is after
- included from various places, but always after
- included in
The access check however is done in:
wp-admin/menu.php
on line 441- which is after
admin_menu
fires inwp-admin/menu.php
on line 328- which is included in
wp-admin/admin.php
on line 93
- which is included in
- which is after
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.