You can achive this with replacing this function:

function apply_for_role_access($account) {
  return $account && $account->uid && (($GLOBALS['user']->uid == $account->uid) && user_access('apply for roles'));
}

with this:

function apply_for_role_access($account) {
  global $user;
  $roles = variable_get('users_apply_roles', array());
  $multiple = variable_get('apply_for_role_multiple', array());
  foreach ($roles as $rid => $role) {
    // Check if the user has this role or has applied for this role
    if (!$user->roles[$rid] && (db_result(db_query("SELECT uid, rid FROM {users_roles_apply} WHERE uid = %d AND rid = %d", $user->uid, $rid)) == 0)) {
      $filter_roles[$rid] = $role;
    }
  }

  return $account && $account->uid && (($user->uid == $account->uid) && user_access('apply for roles')) && is_array($filter_roles);
}

Tyrael

Comments

drewish’s picture

i support this change but i don't think it should be called apply_for_role_access because it conflicts with the naming for hook_access but has a different parameter signature.

Soren Jones’s picture

I'd actually like to take this a step further and make it an option to disable the tab entirely -- that is three options: 1) always on, 2) off when there are no available roles and 3) always off.

drewish’s picture

Soren Jones, what would be the use case for always on or always off? It would be easy to achieve either of those states by using hook_menu_alter() to set the callback's #access parameter.

drewish’s picture

I'd suggest renaming it and moving the bit of code that computes the remaining applications into it's own function:

/**
 * Check that the user is allowed to create applications and that there are
 * roles that they don't yet belong to.
 */
function apply_for_role_apply_access($account) {
  return !empty($account->uid) 
    && $GLOBALS['user']->uid == $account->uid 
    && user_access('apply for roles', $account) 
    && count(apply_for_role_available_roles($account)
  );
}

/**
 * Return an array of the roles that available for application to a user.
 *
 * @param $user User object
 * @return array keyed by role id with the role names as values.
 */
function apply_for_role_available_roles($user) {
  // Get the complete list of roles (other than anonyous)...
  $roles = user_roles(TRUE);
  // ...the roles that can be applied for...
  $enabled = variable_get('users_apply_roles', array());

  // ...the roles the user has already applied for...
  $applied = array();
  $result = db_query("SELECT rid FROM {users_roles_apply} WHERE uid = %d", $user->uid);
  while ($row = db_fetch_object($result)) {
    $applied[$row->rid] = isset($roles[$row->rid]) ? $roles[$row->rid] : t('Invalid role');
  }

  // ... now figure out what's left from the enabled roles list once you remove
  // those they have and those they've applied for.
  $used = $user->roles + $applied;
  return array_diff($enabled, $used);
}
drewish’s picture

though maybe it would make more sense to provide a listing of the pending/denied applications on the tab and show it all the time?

Soren Jones’s picture

Andrew,

Brilliant idea, it's good real estate and it makes sense to do more with it.
I'm still for the option to hide the tab. However, I don't think it's urgent.

Best,
Soren

Soren Jones’s picture

Andrew,

RE: #3, one use case I was imagining for always off was a site using nodes as applications rather than the user tab. Given that feature doesn't exist yet, I guess it's not so urgent. Hah. Anyway, I'm more interested in triggers/actions integration, which you're on, greater permissions granularity (role x can only apply for role 1, but role y can apply for roles 2 & 3), and applications as nodes.

Cheers,
Soren

drewish’s picture

well for applications as a node i'd think workflow would be a much more flexible solution. you'd have better actions/triggers support since they'd be proper nodes but the downside would be providing access control.

Soren Jones’s picture

Version: 6.x-1.4 »
Status: Active » Fixed

Fixed in dev.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

fehin’s picture

I'm wondering if I could use this code for 5x? Thanks.

fehin’s picture

I just noticed that this code has been added to the module but my menu item is still visible even when there is no role to apply for. How can I fix this? Thanks.

webcultist’s picture

Version: » 7.x-1.0-beta9
Status: Closed (fixed) » Active

At first: Thankyou for this module, it's very useful!
Could we use the functionality in this ticket for the 7.x version of the module? As I can see, it just shows us an empty form if there are no roles available.
Greetings

jnicola’s picture

Issue summary: View changes
Status: Active » Closed (fixed)

Testing on 7.x-2.x branch.

Logged in user, without permission to apply for a role cannot view tab, gets access denied at page. With permission can see tab and can access page.

Seems to already be integrated!