Hide WooCommerce Account Endpoints by User Role

do not enter sign

Learn how to hide specific WooCommerce endpoints, and their account menu items, based on user roles.

By default, WooCommerce will add new users to the “Customer” role if they’re created at the point-of-sale. As the website owner/developer, your account is probably in the “Administrator” role. In this tutorial, we’ll hide a couple of the “my account” menu items for the “customer” users. We’ll also add some hooks so that if a customer tries to access an endpoint they’re not allowed to access, we’ll redirect them back to their account’s main front page.

We won’t use any plug-ins to do this – just a couple of simple PHP functions.

How It’ll Work

There are two actions we need to modify:

  • Alter the list of menu items if we detect a user is not authorised to view some of them.
  • Detect when a user tries to access a restricted endpoint, and implement a redirect.

We’ll do this by hooking into woocommerce_account_menu_items (filter) and template_redirect (action).

Before you start, make sure you’re using a custom child theme so you’ve got somewhere to put the custom PHP functions.

WooCommerce account menu items
WooCommerce Account Menu Items

Set Up the Code

In your custom child theme’s folder, create a new file called functions-wc-account.php and paste the following into it.

<?php

/**
 * functions-wc-account.php
 * Modify some WooCommerce account functions.
 */

defined('WPINC') || die();

// Our functions will go in here...
// ...

That’ll do as a placeholder – we’ll come back to it in a minute. Next we need to link this file to the main functions.php file, so… open your custom child theme’s main functions.php file and paste the following into it.

/**
 * WooCommerce Account Functions
 */
require_once dirname(__FILE__) . '/functions-wc-account.php';

That’s the basics in-place. Now we can implement the two hooks and do a bit of testing. We’ll start by creating the redirect when a user tries to access a restricted page.

Redirect Unauthorised Users

Go back to your functions-wc-account.php file and add the following function to it.

function custom_template_redirect() {
	if (is_user_logged_in() && function_exists('WC') && !is_admin() && is_account_page()) {
		$user = wp_get_current_user();
		$is_access_blocked = false;

		// Restrict "downloads" and "payment-methods" to the "administrator" and "editor" roles.
		if (is_wc_endpoint_url('downloads') || is_wc_endpoint_url('payment-methods')) {
			$allowed_roles = array('administrator', 'editor');

			if (!array_intersect($allowed_roles, $user->roles)) {
				$is_access_blocked = true;
			}
		}

		// More endpoint restrictions can go in here...
		// ...

		if ($is_access_blocked) {
			// Redirect to the user's main "my account" page - probably their dashboard.
			wp_safe_redirect(wc_get_page_permalink('myaccount'));
			exit;
		}
	}
}
add_action('template_redirect', 'custom_template_redirect', 5);

Let’s break this down a bit.

infoActions with a lower priority are called before than those with a higher priority.

The call to add_action() hooks the template_redirect action with a priority of 5, and calls our custom_template_redirect() function. Most hooks use a priority of 10. By hooking template_redirect with a priority of 5, we’re ensuring that our code gets called before most of the other hooks.

  • If the user is logged-in, WooCommerce is installed, we’re not in the WP admin area, and we’re trying to load an account page…
    • If we’re trying to view one of the restricted endpoints and the user is not in the allowed roles…
      • set $is_access_blocked = true
    • Possibly check more endpoint restrictions…
      • maybe set $is_access_blocked = true
    • If $is_access_blocked is true…
      • Call the standard WordPress wp_safe_redirect() function to route the user back to their main “my account” page.

That’s all there is to the redirect bit. Save the file and test it by logging in to your site as a customer. If everything’s working properly, when you click on either the “Downloads” or the “Payment Methods” menu item, you’ll be redirected to the Dashboard.

Remove/Hide Menu Items

This section works a lot like the previous function, but instead of just “doing an action”, we’re going to filter an incoming array of menu items and remove (unset(), in PHP) any menu items that the user isn’t allowed to access.

In your functions-wc-account.php file, add the following.

function custom_woocommerce_account_menu_items($items, $endpoints) {
	if (is_user_logged_in() && !is_admin() && is_account_page()) {
		$user = wp_get_current_user();

		// Restrict "downloads" and "payment-methods" to "administrator" and "editor" roles.
		if (!array_intersect(array('administrator', 'editor'), $user->roles)) {
			unset($items['downloads']);
			unset($items['payment-methods']);
		}

		// Do more checks and remove more menu items here, if you want.
	}
	return $items;
}
add_filter('woocommerce_account_menu_items', 'custom_woocommerce_account_menu_items', 10, 2);

The breakdown is similar to our custom_template_redirect() function. Notice that we don’t have function_exists('WC') in our first if() statement – woocommerce_account_menu_items filter is only called by WooCommerce itself.

Save, Test and… All Done

That’s all there is to it. You could certainly use plug-ins to do this sort of thing, but the code here is surgical… It does exactly what we need it to do, and it does it in just a few lines of code. It’s easy-to-read, and easy to extend too.

Have fun customising your WooCommerce account area! 👍

Like This Tutorial?

Let us know

WordPress plugins for developers

Leave a comment