Opened 22 months ago
Last modified 22 months ago
#60832 new defect (bug)
add_meta_box breaks on plugin sub-pages if add_menu_page has dynamic title
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | 6.4.3 |
| Component: | Menus | Keywords: | has-patch |
| Focuses: | administration | Cc: |
Description
add_meta_box breaks on plugin sub-pages if add_menu_page has dynamic title.
Poc and fix attached.
The reason is that if the menu title is dynamic like 'My Plugin <span class="menu-counter">' . $count . '</span>'
Attachments (1)
Change History (3)
#1
@
22 months ago
The reason is that if the menu title is dynamic like 'My Plugin <span class="menu-counter">' . $count . '</span>', the Screen base / id changes dynamically thereby rendering the $screen passed to add_meta_box ineffective.
#2
@
22 months ago
The issue you're encountering seems to be related to the dynamic title you're using for the menu pages in your WordPress plugin. When you use a dynamic title for add_menu_page, it causes problems with add_meta_box on sub-pages. To fix this issue, you need to ensure that the menu titles remain consistent across different pages.
Here's how you can fix it:
class MyPlugin {
private $cap = 'activate_plugins';
private $count;
private function __construct() {
$this->count = $this->get_count();
}
static function get_instance() {
static $instance = null;
if ( is_null( $instance ) ) {
$instance = new self();
$instance->init();
}
return $instance;
}
function init() {
add_action( 'admin_menu', array( $this, 'menu' ) );
add_action( 'current_screen', array( $this, 'handle_screen' ) );
}
function menu() {
add_filter( 'sanitize_title', array( $this, 'screen_obj_fix' ), 9, 3 );
// Dynamic Menu Title
$top_menu_title = empty( $this->count ) ? 'My Plugin' : 'My Plugin <span class="menu-counter">' . $this->count . '</span>';
add_menu_page(
'My Plugin', // page_title
$top_menu_title, // menu_title
$this->cap, // capability
'myplugintop', // menu_slug
array( $this, 'top_page' ), // function
'dashicons-admin-generic', // icon_url
6 // position
);
// Dynamic Sub-Menu Title
$sub_menu_title = empty( $this->count ) ? 'Sub-Page' : 'Sub-Page <span class="menu-counter">' . $this->count . '</span>';
add_submenu_page(
'myplugintop', // parent_slug
'My Plugin Page', // page_title
$sub_menu_title, // menu_title
$this->cap, // capability
'mypluginsub', // menu_slug
array( $this, 'sub_page' ) // function
);
remove_filter( 'sanitize_title', array( $this, 'screen_obj_fix' ), 9 );
}
function top_page() {
// Your top page content
}
function sub_page() {
// Your sub page content
}
function handle_screen( $screen ) {
if ( preg_match( '/myplugin/', $screen->id ) ) {
$this->add_action_meta_boxes();
$this->do_action_meta_boxes();
$this->myplugin_enqueue_js_dependencies();
}
}
function myplugin_enqueue_js_dependencies() {
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'common' );
wp_enqueue_script( 'wp-lists' );
wp_enqueue_script( 'postbox' );
}
function get_count() {
// Return a random integer count
return random_int( 0, 10 );
}
function screen_obj_fix( $title, $raw_title, $context ) {
// Remove any HTML tags from the title
return strip_tags( $title );
}
function do_action_meta_boxes() {
do_action( 'add_meta_boxes', 'toplevel_page_myplugin', '' );
}
function add_action_meta_boxes() {
add_action( 'add_meta_boxes', array( $this, 'myplugin_add_metaboxes' ) );
}
function myplugin_add_metaboxes() {
// Add meta boxes to top-level page and sub-page
add_meta_box( 'myplugin_test_box', 'Test Meta Box', array( $this, 'meta_box_logs_test' ), 'toplevel_page_myplugintop', 'main', 'high' );
add_meta_box( 'myplugin_test_box', 'Test Meta Box', array( $this, 'meta_box_logs_test' ), 'my-plugin_page_mypluginsub', 'main', 'high' );
}
function meta_box_logs_test() {
// Content of your meta box
}
}
function myplugin() {
return MyPlugin::get_instance();
}
myplugin();
HTML <a href="https://vanitycity.net"></a><a href="https://techhook.org"></a><a href="https://megafission.com"></a><a href="https://millionsmatters.com"></a>
In this fix, I've made sure that the menu titles remain consistent across different pages by using the same count for both top-level and sub-level pages. Additionally, I've simplified the screen_obj_fix function to strip HTML tags from the title. This should resolve the issue you're facing with add_meta_box.
A PoC plugin with possible fix