I was extending the user profile to have more menu items. Meaning that I wanted tabs to filter a user view. So I added menu items in my module's hook_menu:
$items['user/%user/view/extprofile'] = array(
'title' => 'For Friends',
'page callback' => 'extprofile_view_filtered',
'page arguments' => array(1, 'for_friends'),
'access callback' => 'user_view_access',
'access arguments' => array(1),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -1,
'file' => 'extprofile.pages.inc',
);
$items['user/%user/view/extprofile_private'] = array(
'title' => 'Private',
'page callback' => 'extprofile_view_filtered',
'page arguments' => array(1, 'private'),
'access callback' => 'user_view_access',
'access arguments' => array(1),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'file' => 'extprofile.pages.inc',
);
Now rebuild menus. The two tabs appear underneath View tab in the user profile. However, when I press Private the Edit menu on the top disappears. As far as I found out this is due to the fact how user_category_load is implemented. Here is the function in from user.module:
function user_category_load($uid, &$map, $index) {
static $user_categories, $accounts;
// Cache $account - this load function will get called for each profile tab.
if (!isset($accounts[$uid])) {
$accounts[$uid] = user_load($uid);
}
$valid = TRUE;
if ($account = $accounts[$uid]) { // <<<<================================
// Since the path is like user/%/edit/category_name, the category name will
// be at a position 2 beyond the index corresponding to the % wildcard.
$category_index = $index + 2;
// Valid categories may contain slashes, and hence need to be imploded.
$category_path = implode('/', array_slice($map, $category_index));
if ($category_path) {
// Check that the requested category exists.
$valid = FALSE;
if (!isset($user_categories)) {
$empty_account = new stdClass();
$user_categories = _user_categories($empty_account);
}
foreach ($user_categories as $category) {
if ($category['name'] == $category_path) {
$valid = TRUE;
// Truncate the map array in case the category name had slashes.
$map = array_slice($map, 0, $category_index);
// Assign the imploded category name to the last map element.
$map[$category_index] = $category_path;
break;
}
}
}
}
return $valid ? $account : FALSE;
}
I marked the line where I think the problem is. The code there is actually always expecting paths of the given form user/%/edit/category_name but my path is a user/%user/view/extprofile_private and of course there is no such category "extprofile_private". So how I solved the problem my problem was to change the marked line into:
...
if (($account = $accounts[$uid]) && $map[0] == 'user' && $map[1] == $index && $map[2] == 'edit') {
...
Comments
Comment #1
damien tournoud commentedThis is a duplicate of #259679: user/[uid]/edit tab not present at user's visits tracker. Already fixed in 7.x, but waiting for investigation on 6.x.