Search code examples
phpwordpressmenu

how to restrict a menu for some userd based on the value of a specific field?


On my primary wp nav, I have a menu item named 'Research' which i want to only be shown for Researchers in wordpress.

Researchers will be defined by a user meta field called wpum_relationship_to_lib which is a multiple choices field including options like: researcher, student, employee and so on.

It is important that researcher must be one of the options the user choses to access that menu and that wpum_relationship_to_lib does not define a Wordpress role.

All menus are primary. Also, I need the menu to be hidden even before login. See my code below which is not restricting menu properly.

function restrict_menu_to_researchers($items, $args) {
  
  // Check if the menu is assigned to the desired location
  if ($args->theme_location === 'primary') {

    // Check if the user is logged in
    if (is_user_logged_in()) {

      $user_id = get_current_user_id();
      $relationship_values = get_user_meta($user_id, 'wpum_relationship_to_lib', true);
            
      // Check if the user is the "researcher" 
      if (is_array($relationship_values) && in_array('researcher', $relationship_values)) {

        // Allow the menu for researchers
        return $items; 

      } else {
        foreach ($items as $key => $item) {
          if ($item->title == 'Research') {
            // Hide the "Research" menu for non-researchers
            unset($items[$key]); 
          }
        } 
      }
    } else {
      foreach ($items as $key => $item) {
        if ($item->title == 'Research') {
          // Hide the "Research" menu for non-logged-in users
          unset($items[$key]);
        }
      }
    }
  }
  return $items;
}
add_filter('wp_nav_menu_objects', 'restrict_menu_to_researchers', 10, 2);

Solution

  • I got the answer. it's interesting that it is case sensitive. and I just needed to use this code as follows. but it works in the test platform without this line. I didn't even know that might be for lower case: (is_array($relationship_values) && in_array('researcher', array_map('strtolower', $relationship_values))) { ...

    and thank you all for your kind help and time. –