I've a plugin divided into multiple pages and files based on classes.
The base file (linked from plugin main file) contains code for menu and submenu pages and provides wordpress with their respective files in a subfolder.
The problem is, that the admin_init
hook isn't working in the submenu page (trying to save values from a form submitted in submenu page).
The main page looks like (the admin_init
hook works fine if used in this file class itself):
class MyPlugin {
public function __construct(){
add_action( 'admin_menu', array( $this, 'add_menu' ) );
}
public function add_menu() {
add_menu_page(
'My Plugin',
'My Plugin',
'manage_options',
MY_PLUGIN_DIR.'/inc/admin/class-my-plugin-home.php',
'',
'dashicons-yes',
89
);
add_submenu_page(
MY_PLUGIN_DIR.'/inc/admin/class-my-plugin-home.php',
'Submenu page',
'Submenu page',
'manage_options',
MY_PLUGIN_DIR.'/inc/admin/class-my-plugin-submenu.php',
''
);
}
}
While the submenuclass-my-plugin-submenu.php file looks like:
function checkit(){
echo "This code is not working or showing (just for example)";
}
add_action( 'admin_init', 'checkit' );
Edit:
Previously not working and now the working version (thanks to Sally CJ) can be found here:
I've a plugin divided into multiple pages and files based on classes.
The base file (linked from plugin main file) contains code for menu and submenu pages and provides wordpress with their respective files in a subfolder.
The problem is, that the admin_init
hook isn't working in the submenu page (trying to save values from a form submitted in submenu page).
The main page looks like (the admin_init
hook works fine if used in this file class itself):
class MyPlugin {
public function __construct(){
add_action( 'admin_menu', array( $this, 'add_menu' ) );
}
public function add_menu() {
add_menu_page(
'My Plugin',
'My Plugin',
'manage_options',
MY_PLUGIN_DIR.'/inc/admin/class-my-plugin-home.php',
'',
'dashicons-yes',
89
);
add_submenu_page(
MY_PLUGIN_DIR.'/inc/admin/class-my-plugin-home.php',
'Submenu page',
'Submenu page',
'manage_options',
MY_PLUGIN_DIR.'/inc/admin/class-my-plugin-submenu.php',
''
);
}
}
While the submenuclass-my-plugin-submenu.php file looks like:
function checkit(){
echo "This code is not working or showing (just for example)";
}
add_action( 'admin_init', 'checkit' );
Edit:
Previously not working and now the working version (thanks to Sally CJ) can be found here: https://github/nabtron/wp-admin-init-test-plugin
(Updated answer)
Looking at the simplified plugin source, the following works:
// In class-init-test.php
public function __construct(){
add_action( 'admin_init', array( $this, 'page_init' ) );
...
}
because when that add_action()
is called, the admin_init
action is not yet fired. Hence Init_test::page_init()
gets called.
However, the following doesn't work because admin_init
has already been fired by the time you call add_action( 'admin_init', ... )
:
In class-init-test-home.php
:
public function __construct() {
add_action( 'admin_init', array( $this, 'save' ) );
...
}
In class-init-test-submenu.php
:
function save(){
...
}
add_action( 'admin_init', 'save' );
And if you want to confirm whether admin_init
has been fired or not, add this before the add_action()
call:
var_dump( did_action( 'admin_init' ) );
To overcome the issue, you can create a static method/function in your menu/submenu class, and hook the method from the Init_test
constructor. Example for the Init_Test_Home
class:
// In class-init-test.php
/* This is a simplified example! You'd need to adjust the `Init_Test_Home` class
e.g. do `public static function save()` instead of `public function save()`,
and you should actually load the class prior to calling the `add_action()`; or
perhaps in init-test.php.
*/
public function __construct(){
add_action( 'admin_init', array( Init_Test_Home, 'save' ) );
...
}
Or you can try the code/approach I previously suggested. :) But here, it's slightly different and based on your existing code; and this one is, again, for the Init_Test_Home
class, but you can follow the same steps for the submenu class:
In class-init-test.php
:
public function add_menu() {
// Load and instantiate the class - $init_test_home is defined in the class file.
include INIT_TEST_DIR . '/inc/admin/class-init-test-home.php';
add_menu_page(
'Init Test',
'Init Test',
'manage_options',
'init-test-home', // Use a slug other than the class file path.
array( $init_test_home, 'admin_page' ),
'dashicons-yes',
89
);
...
}
In class-init-test-home.php
:
public function __construct() {
add_action( 'admin_init', array( $this, 'save' ) );
}
public function admin_page() {
require_once('views/init-test-home.php');
}
Define INIT_TEST_DIR
like so:
define( 'INIT_TEST_DIR', plugin_dir_path( __FILE__ ) );
Hopefully this answer is more helpful!
admin_init
has already been fired. So you should probably just hook from the base class, or the main plugin file. – Sally CJ Commented Nov 29, 2018 at 2:29