Hi

I have a created a form that returns information to mymodule_item_form_page.

I have set up through the menu hook access permissions for the items that get returned but I would like to add the ability to allow additional users who would not normally have access to the item to be able to see it.

I have created a table that contains the id of the item and the uid from users,

does anyone have an example of how I can manage access permissions in this way please (i.e. group access + defined users

Thanks

Comments

Jaypan’s picture

In your hook_menu(), define a custom access callback:

function hook_menu()
{
  $menu['some/path'] = array
  (
    // ...
    'access callback' => 'custom_access_callback',
  );

  return $menu;
}

Then do your tests in that access callback:

function custom_access_callback()
{
  global $user;

  if(user_access('some permission'))
  {
    return TRUE;
  }

  if(db_query('SELECT 1 FROM {access_table} WHERE uid = :uid', array(':uid' => $user->uid))->fetchField())
  {
    return TRUE;
  }
}
gibbo1715’s picture

Thats great thanks

gibbo1715’s picture

If I wanted to use this function for multiple menu items (item/view, item/edit and item/delete) how would I wrap those in an if statement so I only need manage my permissions through the one function?

Many Thanks

Jaypan’s picture

You can pass a static value for the access argument to indicate what it is you're doing. Here is an example for a delete element:

function hook_menu()
{
  $menu['item/delete/%'] = array
  (
    // ...
    'access callback' => 'my_access_callback',
    'access arguments' => array('delete', 2),
  );
}

function my_access_callback($op, $id)
{
  if($op == 'delete')
  {
    // Do your stuff here
  }
}
gibbo1715’s picture

Great, thanks, I ll see if I can get that working, assume if I had that the other way round %/delete it would be 'access arguments' => array('delete', 3),?

Jaypan’s picture

No, it would be array('delete', 1)

gibbo1715’s picture

Sorry but don't think I quite understand this yet, Might be I'm not totally clear on how the menu system works yet

So if I wanted to do this from the following (As I'm running through hook_load()) how would I get the second argument?

 $items['meeting/%meeting'] = array
    (
        'title' => 'View item',
        'page callback' => 'meeting_view_item_page',
        'page arguments' => array(1),
        'access callback' => 'my_access_callback',
        'access arguments' => array(?),
        'file' => 'meetings.pages.inc', // File where my pages are kept
        'file path' => drupal_get_path('module', 'meetings'), //Path to my pages.inc file
    );
    $items['meeting/%meeting/view'] = array
    (
        'title' => 'Overview',
        'page arguments' => array(1),
         'access callback' => 'my_access_callback',
        'access arguments' => array(?),
        'type' => MENU_DEFAULT_LOCAL_TASK,
        'weight' => -4,
    );
Jaypan’s picture

Sorry, I don't understand the question, nor the reference to hook_load().

But the access arguments for both your paths would be:

'access arguments' => array('view', 1),
gibbo1715’s picture

I tried that but I get a warning as follows

Warning: Missing argument 2 for my_access_callback() in my_access_callback() , I have cleared the cache

In my function I have

function my_access_callback($op, $id)
{
  global $user;
  
  if($op == 'view')
  {
    if(user_access('access content'))
  {
    return TRUE;
  }

  }
}

Hook_menu

 $items['meeting/%meeting'] = array
    (
        'title' => 'View item',
        'page callback' => 'meeting_view_item_page',
        'page arguments' => array(1),
        'access callback' => 'my_access_callback',
        'access arguments' => array('view', 1),

Is that because I don't appear to be passing a second argument? works if I remove that

Jaypan’s picture

Are you showing your actual code? I don't see how that error is possible based on the code you are showing. In your hook_menu(), your access arguments are here:

'access arguments' => array('view', 1),

The first argument is 'view', and the second argument will be the result of meeting_load(). These become the arguments in my_access_callback():

function my_access_callback($op, $id)

The $op will be 'view', and the $id will be the result of meeting_load(). So I can't see how you would be getting that error, as both arguments are defined, and so you would never be missing argument 2.

gibbo1715’s picture

This is my actual code so no idea either, I'll keep playing and see if I can work it out,

I do run my database query in my meeting_load() function and that returns the database result which is working so I know something is returned, but it is the db object and not the id in the argument, maybe that's my issue?

function meeting_load($id)
...
$records = meetings_db_select($table, 'n' ,$id, '=');
return $records;

Many Thanks

Jaypan’s picture

I'm thinking you must not have cleared your cache after changing your hook menu. That's the only way it could give you that error.

gibbo1715’s picture

was sure i had..thanks