I was trying to hide some menu tabs and mistakenly used access callback and set it to false, rather than setting type to MENU_CALLBACK. But now that I've changed my module and flushed all the cache, whenever I load the module the setting for access callback remains false.

First question: If you set an element in the menu_router database that didn't exist before, does it always come back the same? Ie even though my module only sets Type, will access callback still be set to false?

Assuming the answer to that is yes, I manually set the callback to user_edit_access. But now its expecting an argument and I don't know what to give it. I tried $GLOBALS['user']->uid and plain old $user->uid. Both are giving me errors.

2nd Question: What argument does user_edit_access expect? I want the same functionality as profile and user start with ie a user can edit his/her own profile, and so can users with the appropriate permission.

Example code to show what I'm talking about. All this is happening in hook_menu_alter:

//First mistake:
$items['user/%user/edit/Box 1']['access callback'] = FALSE;

//First attempt to fix, line above is changed to:
$items['user/%user/edit/Box 1']['type'] = MENU_CALLBACK;

//DB still shows 0 for access callback, now I try this:
$items['user/%user/edit/Box 1']['access callback'] = user_edit_access;

//Error says drupal wants an argument, so I try:
$items['user/%user/edit/Box 1']['access arguments'] = $user->uid;

// and then try
$items['user/%user/edit/Box 1']['access arguments'] = $GLOBALS['user']->uid;

Thanks in advance, advanced drupalers!
- Ryan

Comments

jaypan’s picture

This was the closest one:

$items['user/%user/edit/Box 1']['access callback'] = user_edit_access;

You were missing quotes around the function name:

$items['user/%user/edit/Box 1']['access callback'] = 'user_edit_access';

Contact me to contract me for D7 -> D10/11 migrations.

jaypan’s picture

Just to add a little more to this, when you are defining access arguments, you need to give an array of permissions defined in hook_perm. For example:

 function mymodule_perm()
{
  return array('my_permission');
}

function mymodule_menu()
{
  $menu['path/to/define'] = array
  (
    //type, description etc
    'access arguments' => array('my_permission'),
  );
  return $menu;
} 

This will check to see if the user is part of a role that has the 'my_permission' permission when trying to access www.example.com/path/to/define.

Contact me to contract me for D7 -> D10/11 migrations.

rschwab’s picture

Thank you!

Taking a look at the existing permissions, I'm guessing the default access arguments would look something like this:

'access arguments' => array('edit any profile content','edit own profile content'),

EDIT: My above code is lies! Here is what I discovered as the default, via user.module line 1079:

  $items['user/%user_category/edit'] = array(
    'title' => 'Edit',
    'page callback' => 'user_edit',
// Here is the bugger:
    'page arguments' => array(1), 
    'access callback' => 'user_edit_access',
    'access arguments' => array(1),
    'type' => MENU_LOCAL_TASK,
    'load arguments' => array('%map', '%index'),
    'file' => 'user.pages.inc',
  );

Enjoy Drupalers!
- Ryan

rschwab’s picture

Ok can anyone explain this insanity to me? I'm calling hook_menu_alter like so:

/**
* Implementation of hook_menu_alter
*/
function iheartmodule_menu_alter(&$items) {

	$items['user/%/edit/Box 1']['type'] = MENU_CALLBACK;
	$items['user/%/edit/Box 2']['type'] = MENU_CALLBACK;
	$items['user/%/edit/Box 3']['type'] = MENU_CALLBACK;
	$items['user/%/edit/Box 4']['type'] = MENU_CALLBACK;
	$items['user/%/edit/Box 5']['type'] = MENU_CALLBACK;
	$items['user/%/edit/Box 6']['type'] = MENU_CALLBACK;
	$items['user/%/edit/Fun Facts']['type'] = MENU_CALLBACK;
	$items['user/%/edit/Fun Facts 2']['type'] = MENU_CALLBACK;
	
	// Alter some menu tab titles
	$items['user/%/imce']['title'] = 'Upload photos';
	
	return $items;
}

When I enable this module and look in phpmyadmin, all these things are happening:
- Menu type is set to 4, or MENU_CALLBACK. Good! Thats what I wanted.
- Access Callback is set to 0, or FALSE. WTF?? Noone can get to these pages now.
- Access arguments and load functions all reset. My profiles are now broken.

What am I doing wrong? Why does Drupal hate me so?

rschwab’s picture

The problem was apparently in the wildcard I was using. the wildcard is responsible for setting the load functions, upon which everything else apparently rests. Here is the working code:

/**
* Implementation of hook_menu_alter
*/

function iheartmodule_menu_alter(&$items) {

	$items['user/%user_category/edit/Box 1']['type'] = MENU_CALLBACK;
	$items['user/%user_category/edit/Box 2']['type'] = MENU_CALLBACK;
	$items['user/%user_category/edit/Box 3']['type'] = MENU_CALLBACK;
	$items['user/%user_category/edit/Box 4']['type'] = MENU_CALLBACK;
	$items['user/%user_category/edit/Box 5']['type'] = MENU_CALLBACK;
	$items['user/%user_category/edit/Box 6']['type'] = MENU_CALLBACK;
	$items['user/%user_category/edit/Fun Facts']['type'] = MENU_CALLBACK;
	$items['user/%user_category/edit/Fun Facts 2']['type'] = MENU_CALLBACK;

	// Alter some menu tab titles
	$items['user/%user/imce']['title'] = 'Upload photos';

	// Hide IAC client profile tab from non-staff
	$items['user/%user_category/edit/IAC Client Profile']['access callback'] = 'user_access';
	$items['user/%user_category/edit/IAC Client Profile']['access arguments'] = array('update client profile');	
}

To find which functions needed to be loaded for the menu items, I had to look in phpmyadmin at the database before using this module. So you'll note that profile sections invoke the load functions user_category_load, and therefore need a wildcard of %user_category.

Also, don't try to return $items at the end of menu_alter...it doesn't need it and probably breaks it.

Breathing a huge sigh of relief,
- Ryan

Tafa’s picture

Hello all,

While I managed to get rid of the tabs, a funny thing happened as I tried to link an URL from one of these tabs back to a menu link I created for. In particular, I wanted to create a "settings link from a primary menu tab. But instead of having the edit menu, I am now redirected to my profile. In other words, I am not able to access my edit profile account even though the URL is correct.
Any ideas here more than welcome.
T

ptocheia’s picture

I've been going crazy trying to figure out why, in the module I'm building, I could add to my database, but could not edit or delete it's contents. Turns out my problem was with my improperly named wildcards, which I wouldn't have realized if I hadn't stumbled across this post. Thanks!