I would like specific users to only see the WooCommerce -> Settings -> Shipping menu. I've managed to remove other tabs e.g. Products, Payments, etc, but stuck on the following 2 things that I want to to accomplish:
- Remove the "GENERAL" Tab in WooCommerce Settings.
- Remove the "ORDER STATUSES" Tab from a plugin. (Note: this isn't a tab exactly, the slug is 'edit.php?post_type=wc_order_status')
When I try to remove the GENERAL tab, it eliminates the entire Settings menu. As for the 'Order Statuses', my code just doesn't work.
add_filter( 'woocommerce_settings_tabs_array', 'remove_woocommerce_setting_tabs', 200, 1 );
function remove_woocommerce_setting_tabs( $array ) {
global $current_user;
//Declare the tabs we want to hide
$tabs_to_hide = array(
'general' => 'General', //this one removes the entire Settings menu
'wc_order_status' => 'Order Statuses'// this doesn't work, maybe bc it's a post_type
);
// Remove tab if user role is shipping_manager
if ( in_array("shipping_manager", $$current_user->roles) ) {
$array = array_diff_key($array, $tabs_to_hide);
}
}
I had also tried the below code to remove the ORDER STATUSES tab, but still no luck:
add_action( 'admin_menu', 'remove_order_statuses_tab', 999);
function remove_order_statuses_tab()
{
global $current_user;
if ( in_array("shipping_manager", $current_user->roles) ) {
remove_menu_page( 'edit.php?post_type=wc_order_status' ); //not working either
}
}
I would like specific users to only see the WooCommerce -> Settings -> Shipping menu. I've managed to remove other tabs e.g. Products, Payments, etc, but stuck on the following 2 things that I want to to accomplish:
- Remove the "GENERAL" Tab in WooCommerce Settings.
- Remove the "ORDER STATUSES" Tab from a plugin. (Note: this isn't a tab exactly, the slug is 'edit.php?post_type=wc_order_status')
When I try to remove the GENERAL tab, it eliminates the entire Settings menu. As for the 'Order Statuses', my code just doesn't work.
add_filter( 'woocommerce_settings_tabs_array', 'remove_woocommerce_setting_tabs', 200, 1 );
function remove_woocommerce_setting_tabs( $array ) {
global $current_user;
//Declare the tabs we want to hide
$tabs_to_hide = array(
'general' => 'General', //this one removes the entire Settings menu
'wc_order_status' => 'Order Statuses'// this doesn't work, maybe bc it's a post_type
);
// Remove tab if user role is shipping_manager
if ( in_array("shipping_manager", $$current_user->roles) ) {
$array = array_diff_key($array, $tabs_to_hide);
}
}
I had also tried the below code to remove the ORDER STATUSES tab, but still no luck:
add_action( 'admin_menu', 'remove_order_statuses_tab', 999);
function remove_order_statuses_tab()
{
global $current_user;
if ( in_array("shipping_manager", $current_user->roles) ) {
remove_menu_page( 'edit.php?post_type=wc_order_status' ); //not working either
}
}
Share
Improve this question
asked Apr 17, 2020 at 22:00
LesLes
1235 bronze badges
5
- So you want them to still have access to the Shipping Options? Because if you want them to not have access to any of it, that's an easier fix. – Tony Djukic Commented Apr 18, 2020 at 0:12
- Correct. I just want them to have only the Shipping Options available to them. I don't want them to have access to the other settings options; this user role is to manage shipping options only. – Les Commented Apr 19, 2020 at 13:49
- Is the Order Statuses tab input by a secondary plugin? I seem to remember that being the case on a site I once worked on. – Tony Djukic Commented Apr 19, 2020 at 16:49
- Wow, this is infuriating... ...I've been testing a bunch of methods and everything works EXCEPT it always first loads the general settings screen. Just working on resolving that. – Tony Djukic Commented Apr 19, 2020 at 17:42
- To the question on Order Statuses - yes, this is a 3rd party plugin and is accessed as follows: 'edit.php?post_type=wc_order_status'. Unlike the other tabs that are accessed as 'admin.php?page=wc-settings&tab=shipping' for example. – Les Commented Apr 19, 2020 at 18:07
2 Answers
Reset to default 1So it turns out that because of the way the WC settings page is built, that you can't unset the general screen. The tab, sure, but clicking on the WooCommerce settings in the dashboard submenu will always load the General settings, even if the tab is missing. So I wrote two different functions to remove all of it and the second function just so happens to allow us to also remove the Order Status screen. (Not sure about the tab though, but you can hide that with CSS because we'll already be making sure users can't navigate to that panel if they're lowly shipping_managers
.)
add_filter( 'woocommerce_settings_tabs_array', 'remove_woocommerce_setting_tabs', 200, 1 );
function remove_woocommerce_setting_tabs( $array ) {
global $current_user;
if( in_array( 'shipping_manager', $current_user->roles ) ) {
unset( $array[ 'general' ] );
unset( $array[ 'products' ] );
unset( $array[ 'tax' ] );
unset( $array[ 'checkout' ] );
unset( $array[ 'account' ] );
unset( $array[ 'email' ] );
unset( $array[ 'integration' ] );
unset( $array[ 'advanced' ] );
echo '<script>jQuery( document ).ready( function($) { $( \'[href="' . admin_url() . '/edit.php?post_type= wc_order_status"]\' ).hide(); } );</script>';
}
return $array;
}
add_action( 'admin_init', 'redirect_from_settings_screen' );
function redirect_from_settings_screen() {
global $pagenow;
global $current_user;
if( in_array( 'shipping_manager', $current_user->roles ) ) {
if( $pagenow == 'admin.php' && isset( $_GET['page'] ) && $_GET['page'] == 'wc-settings' && !isset( $_GET['tab'] ) ) {
wp_redirect( admin_url( '/admin.php?page=wc-settings&tab=shipping' ) );
exit;
}
if( $pagenow == 'edit.php' && isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_order_status' ) {
wp_redirect( admin_url( '/admin.php?page=wc-settings&tab=shipping' ) );
exit;
}
}
}
So here's a breakdown, the first function allow us to remove all of the WC Settings Tabs, including General. Works like a treat except for the fact that navigating to the WC Settings screen will, by default, load the General settings fields. So that's no good. But, everything else is gone and the shipping tab is visible and works perfectly.
Next we have a function to redirect access to the General Settings screen admin.php?page=wc-settings
to route people to admin.php?page=wc-settings&tab=shipping
.
Then I add on a second check to see if $pagenow
is on the Order Status screen, check for the post_type
and if it's wc_order_status
and if it is, redirect it to Shipping again.
Now, the first function removes the tabs for all those different settings panels, but a user could technically still access the URLs if they know them. So you could repeat the set-up of the General -> Shipping redirect, or do it as an array of tabs and make sure that even manual attempts to access the other tabs reroute to Shipping.
NOTE
I don't have a shipping_manager
user role to test with so hopefully that won't pose any problems.
Here is the simple answer
add_filter( 'woocommerce_settings_tabs_array', 'remove_woocommerce_setting_tabs', 200, 1 );
function remove_woocommerce_setting_tabs( $array ) {
global $current_user;
// Remove tab if user role is shipping_manager
if ( in_array( "shipping_manager", $current_user->roles ) ) {
unset( $array[ 'general' ] );
?>
<script>
document.querySelector("[href='<?php echo esc_url( admin_url( 'edit.php?post_type=wc_order_status' ) ); ?>']").style.display = 'none';
</script>
<?php
}
return $array;
}