0

I have:

function hook_menu()  {
    $items = array();
    $items['experiment-2'] = array(
        'title' => 'Experiment 2',
        'page callback' => 'drupal_get_form',
        'page arguments' => array('experiment_form'),
        'access callback' => 'user_can_access_experiment',
        'file' => 'includes/experiment-2.form.inc',
        'type' => MENU_NORMAL_ITEM,
      );

    ...

This will call:

function user_can_access_experiment() { }

But I want to be able to call it something like:

function user_can_access_experiment($experimentID) { }

And then somehow let hook_menu call the function as user_can_access_experiment(1) or user_can_access_experiment(2) or whatever.

Is this possible?

1
5

If I understand your query right the access callback needs to accept a parameter based on which it decides whether or not to return TRUE for the menu path. This should be achievable using access arguments, like

'access arguments' => array($experimentID),

quoting from the hook_menu API documentation

"access arguments": An array of arguments to pass to the access callback function, with path component substitution as described above. If the access callback is inherited (see above), the access arguments will be inherited with it, unless overridden in the child menu item.

The passed argument, in your case the $experimentID could be either from any custom computation like a value from the user object or even a part of your query parameters.

1
  • Given '/foo/bar/barfoo' as path and 'access callback' => '_mymodule_check_arg', 'access arguments' => array(2) would pass 'barfoo' into _mymodule_check_arg($arg_from_path). Apr 30 '19 at 15:18
1

You should use "access arguments" to indicate it. This array key is waiting for an array.

cf : https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_menu/7

1

"access callback": A function returning TRUE if the user has access rights to this menu item, and FALSE if not. It can also be a boolean constant instead of a function, and you can also use numeric values (will be cast to boolean). Defaults to user_access() unless a value is inherited from the parent menu item; only MENU_DEFAULT_LOCAL_TASK items can inherit access callbacks. To use the user_access() default callback, you must specify the permission to check as 'access arguments' (see below).

"access arguments": An array of arguments to pass to the access callback function, with path component substitution as described above. If the access callback is inherited (see above), the access arguments will be inherited with it, unless overridden in the child menu item.

This example may helps you:

function hook_menu()  {
    $items = array();
    $items['experiment-2'] = array(
        'title' => 'Experiment 2',
        'page callback' => 'drupal_get_form',
        'page arguments' => array('experiment_form'),
        'access callback' => 'user_has_role',
        'access arguments' => array(array('Role 1', 'Role 2')),
        'file' => 'includes/experiment-2.form.inc',
        'type' => MENU_NORMAL_ITEM,
      );

    return $items;
}


function user_has_role($roles) {
    if (user_is_logged_in()) {
        global $user;
        if (in_array('administrator', $user->roles)) {
            return TRUE;
        }
        foreach ($roles as $role) {
            if (in_array($role, $user->roles)) {
                return TRUE;
            }
        }
    }
    else {
        return FALSE;
    }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.