I want to basically override a plugin class function in my Wordpress functions.php. I want to give access to the editor for the plugin settings. is there any way? because it has a constructor function. will be very thankful.
Plugin code
class BulkImport
{
function __construct()
{
add_action("admin_menu", array($this, 'menu'));
}
function menu()
{
add_submenu_page('edit.php?post_type=wpdmpro', __( "Bulk Import ‹ Download Manager" , "download-manager" ), __( "Bulk Import" , "download-manager" ), WPDM_MENU_ACCESS_CAP, 'importable-files', array($this, 'UI'));
}
}
I want to replace the WPDM_MENU_ACCESS_CAP
to edit_pages
Thanks.
Short answer, have you tried using an Admin Menu editor plugin such as Admin Menu Editor ? I don't have experience with it and thus can't vouch for it, but it seems well reviewed and managed.
Edit : If they are doing a capability check on the UI
method, as well as the admin_menu
hook, you may just be better off using the WP_Role::add_cap()
to add the WPDM_MENU_ACCESS_CAP
to the editor
role. You would have to make sure that capability doesn't give them access to other things they shouldn't though. Based on the name of the constant, it sounds like it would be fine, but you'd need to do a cursory glance through the plugin to make sure.
Long answer: with WordPress, generally if things are done correctly, you rarely need to "override" plugin classes, class methods, or functions (though, sometimes you do). One of the great things about WordPress is its Hooks system, specifically its Action Hooks .
When a plugin usesadd_action()
and omits the third argument ( $priority
) gets set to 10
by default. The way priority works is that lower numbers get run on that hook first, so take the following:
add_action( 'some_hook', 'some_other_function' );
add_action( 'some_hook', 'some_function', 3 );
add_action( 'some_hook', 'func', 999 );
Despite the order these were written in, when some_hook
runs on that request, some_function
will run first (priority 3), then some_other_function
(default priority of 10), and lastly func
will run, with a priority of 999.
What this is nice for, is that func
has access to modify or undo anything set in some_function
and some_other_function
.
Now your plugin has this line add_action("admin_menu", array($this, 'menu'));
, which adds its own menu
method to the admin_menu
hook with a priority of 10
. This means you can write your own function and hook it to the admin_menu
hook with a lower (higher number) priority, such as 11
or 99
. In that function, you can use the remove_submenu_page()
function to remove the page added by the plugin, and then use the add_menu_page()
function to add it back in, but change any of the parameters! For instance:
add_action( 'admin_menu', 'change_BulkImport_submenu', 11 );
function change_BulkImport_submenu(){
remove_submenu_page( 'edit.php?post_type=wpdmpro', 'importable-files' );
add_submenu_page('edit.php?post_type=wpdmpro', __( "Bulk Import ‹ Download Manager" , "download-manager" ), __( "Bulk Import" , "download-manager" ), 'edit_pages', 'importable-files', array('BulkImport', 'UI') );
}
Here's where it can be a bit complicated depending on how the plugin you're working with. in the last argument for add_submenu_page
, you'll need to grab the globally instantiated class method, call it as a static method, or instantiate a new instance of the class and use the method there. I took a stab at what may be in there, but without seeing the plugin, I can't tell. For an example, I have a plugin where I have to mess with Elegant Theme's "Bloom" plugin, and in order to do it I call global $et_bloom
and then remove_action( 'wp_footer', [$et_bloom, 'display_flyin'] );
on the hook that there's a conflicy.
You'll see posts about modifying the
global $menu, $submenu
(or$GLOBALS['submenu']
), but those only work if you're restricting permissions, not relaxing them. This is because very early in theadd_submenu_page()
it checks the return value forcurrent_user_can($capability)
and if the current user doesn't have it, it will be added to the global$_wp_submenu_nopriv
and then the function returnsfalse
right there (so the item doesn't get added).
In general, I prefer the unhook/rehook method if possible, because it leaves a clearer trail of what you're doing, and why, and it works in both directions (restricting/relaxing). But, in the admin_menu
hook, you have access to the global $menu
and global $submenu
variables, which you can modify before they get rendered to the page, but after the permissions have already been determined, it can get real ugly relaxing permissions on this hook, though restricting is nice and simple, here's a quick example:
add_action( 'admin_menu', function(){
global $menu, $submenu;
// Is the submenu I want in the page I want?
if( isset($submenu['my-top-level-slug']) ){
// Yes, we have an array of arrays (each submenu item = array)
foreach( $submenu['my-top-level-slug'] as $index => $submenu_array ){
//var_dump( $index );
// Search these arrays for my secondary slug
$search = array_search('my-secondary-slug', $submenu_array );
// This will return the submenu index if we found it, false if not
if( $search != false ){
// We found it! It's in this $index. Modify the [1]st element (permissions)
$submenu['my-top-level-slug'][$index][1] = 'manage_options';
// Stop processing this loop, we found what we came for.
break;
}
}
}
}, 11 );
More generally (but thanks to @XHynx's specific solution):
functions.php
remove_action("admin_menu", 'menu');
add_action("admin_menu", 'my_menu');
function my_menu(){
/*copy the original function here and modify it */
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.