array(
'arguments' => array('form' => NULL),
),
'apply_for_role_status' => array(
'arguments' => array('status' => NULL),
)
);
}
/**
* Implementation of hook_help().
*/
function apply_for_role_help($path, $arg) {
switch ($path) {
case 'admin/help#apply_for_role':
return $explanation = '
'. t('The Apply for roles module allows users to apply for roles from their user page and allows administrators to easily view, approve and delete role applications.', array('@url' => url('admin/settings/apply_for_role'))) .'
';
}
}
/**
* Implementation of hook_perm().
*/
function apply_for_role_perm() {
return array('administer apply for role', 'approve role applications', 'apply for roles');
}
/**
* Implementation of hook_access().
*/
function apply_for_role_access($account) {
return $account && $account->uid && (($GLOBALS['user']->uid == $account->uid) && user_access('apply for roles'));
}
/**
* Implementation of hook_menu().
*/
function apply_for_role_menu() {
$items['admin/settings/apply_for_role'] = array(
'title' => t('Apply for role administration'),
'description' => t('Administer which roles users can apply for.'),
'page callback' => 'drupal_get_form',
'page arguments' => array('apply_for_role_settings_form'),
'access arguments' => array('administer apply for role'),
);
$items['admin/user/apply_for_role'] = array(
'title' => t('Manage role applications'),
'description' => t('View, approve and delete role applications.'),
'page callback' => 'drupal_get_form',
'page arguments' => array('apply_for_role_admin_form'),
'access arguments' => array('approve role applications'),
);
$items['admin/user/apply_for_role/approve/%user/%'] = array(
'title' => t('Approve role application'),
'page callback' => 'drupal_get_form',
'page arguments' => array('apply_for_role_approve_form', 4, 5),
'access arguments' => array('approve role applications'),
'type' => MENU_CALLBACK,
);
$items['admin/user/apply_for_role/deny/%user/%'] = array(
'title' => t('Deny role application'),
'page callback' => 'drupal_get_form',
'page arguments' => array('apply_for_role_deny_form', 4, 5),
'access arguments' => array('approve role applications'),
'type' => MENU_CALLBACK,
);
$items['admin/user/apply_for_role/remove/%user/%'] = array(
'title' => t('Remove role application'),
'page callback' => 'drupal_get_form',
'page arguments' => array('apply_for_role_remove_form', 4, 5),
'access arguments' => array('approve role applications'),
'type' => MENU_CALLBACK,
);
$items['user/%user/apply_for_role'] = array(
'title' => t('Apply for role'),
'page callback' => 'drupal_get_form',
'page arguments' => array('apply_for_role_apply_form', 1),
'access callback' => 'apply_for_role_access',
'access arguments' => array(1),
'type' => MENU_LOCAL_TASK,
);
return $items;
}
/**
* Administration
*/
function apply_for_role_settings_form() {
$selected_roles = variable_get('users_apply_roles', array());
foreach ((array)$selected_roles as $rid => $value) {
if ($rid > 2) {
$selected_rids[] = $rid;
}
}
$form['options'] = array(
'#type' => 'fieldset',
'#title' => t('Apply for role options'),
);
$form['options']['multiple'] = array(
'#type' => 'radios',
'#title' => t('Allow multiple roles per application'),
'#options' => array(t('No'), t('Yes')),
'#default_value' => variable_get('apply_for_role_multiple', 0),
'#description' => t("Chosing 'no' will limit users to applying for only one role per role application. Choosing 'yes' will allow users to apply for multiple roles per role application."),
'#required' => TRUE,
);
$form['options']['register'] = array(
'#type' => 'radios',
'#title' => t('Allow users to apply for roles on registration'),
'#options' => array(t('No'), t('Yes')),
'#default_value' => variable_get('apply_for_role_register', 0),
'#description' => t("Choosing 'yes' will allow users to apply for roles when creating a new account."),
'#required' => TRUE,
);
$roles = (user_roles(TRUE));
unset($roles[DRUPAL_AUTHENTICATED_RID]);
$form['roles'] = array(
'#type' => 'checkboxes',
'#title' => t('Roles'),
'#default_value' => isset($selected_rids) ? $selected_rids : array(2),
'#options' => $roles,
'#description' => t('Select the roles that users will be able to apply for.'),
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Update'),
);
return $form;
}
function apply_for_role_settings_form_submit($form, &$form_state) {
$roles = user_roles(TRUE);
foreach ($form_state['values']['roles'] as $key => $value) {
if ($value) {
$selected_roles[$value] = $roles[$value];
}
}
variable_set('users_apply_roles', $selected_roles);
variable_set('apply_for_role_multiple', $form['options']['multiple']['#value']);
variable_set('apply_for_role_register', $form['options']['register']['#value']);
drupal_set_message(t('Apply for role settings have been saved.'));
$form_state['redirect'] = 'admin/settings/apply_for_role';
return;
}
/**
* User management
*/
function apply_for_role_admin_form(&$form_state) {
$header = array(
array('data' => t('Username'), 'field' => 'u.name'),
array('data' => t('Current Roles')),
array('data' => t('Applying For'), 'field' => 'rid'),
array('data' => t('Applied'), 'field' => 'apply_date', 'sort' => 'desc'),
array('data' => t('Status'), 'field' => 'approved'),
array('data' => t('Processed'), 'field' => 'approve_date'),
array('data' => t('Operations'), 'colspan' => 2),
);
$form['#header'] = $header;
$roles = user_roles(TRUE);
$result = db_query("SELECT * FROM {users_roles_apply} a LEFT JOIN {users} u ON u.uid = a.uid ". tablesort_sql($header));
while ($row = db_fetch_object($result)) {
$user = user_load(array('uid' => $row->uid));
$form['apps'][$row->uid][$row->rid]['user'] = array(
'#value' => theme('username', $user),
);
$form['apps'][$row->uid][$row->rid]['role'] = array(
'#value' => isset($roles[$row->rid]) ? check_plain($roles[$row->rid]) : t('Invalid Role'),
);
$form['apps'][$row->uid][$row->rid]['current_roles'] = array(
'#value' => filter_xss_admin(implode('
', $user->roles)),
);
$form['apps'][$row->uid][$row->rid]['apply_date'] = array(
'#value' => format_date($row->apply_date),
);
$form['apps'][$row->uid][$row->rid]['status'] = array(
'#value' => theme('apply_for_role_status', $row->approved),
);
$form['apps'][$row->uid][$row->rid]['approve_date'] = array(
'#value' => empty($row->approve_date) ? '' : format_date($row->approve_date),
);
if ($row->approved == 0) {
$form['apps'][$row->uid][$row->rid]['approve'] = array(
'#value' => l(t('Approve'), 'admin/user/apply_for_role/approve/'. $row->uid .'/'. $row->rid, array('title' => t('Approve this user'))),
);
$form['apps'][$row->uid][$row->rid]['deny'] = array(
'#value' => l(t('Deny'), 'admin/user/apply_for_role/deny/'. $row->uid .'/'. $row->rid, array('title' => t('Deny this user'))),
);
}
$form['apps'][$row->uid][$row->rid]['delete'] = array(
'#value' => l(t('Delete'), 'admin/user/apply_for_role/remove/'. $row->uid .'/'. $row->rid, array('title' => t('Remove application'))),
);
}
return $form;
}
function theme_apply_for_role_admin_form($form) {
$rows = array();
foreach (element_children($form['apps']) as $uid) {
foreach (element_children($form['apps'][$uid]) as $rid) {
$rows[] = array(
array('data' => drupal_render($form['apps'][$uid][$rid]['user'])),
array('data' => drupal_render($form['apps'][$uid][$rid]['current_roles'])),
array('data' => drupal_render($form['apps'][$uid][$rid]['role'])),
array('data' => drupal_render($form['apps'][$uid][$rid]['apply_date'])),
array('data' => drupal_render($form['apps'][$uid][$rid]['status'])),
array('data' => drupal_render($form['apps'][$uid][$rid]['approve_date'])),
array('data' => drupal_render($form['apps'][$uid][$rid]['approve'])),
array('data' => drupal_render($form['apps'][$uid][$rid]['deny'])),
array('data' => drupal_render($form['apps'][$uid][$rid]['delete'])),
);
}
}
if (count($rows) == 0) {
$rows[] = array(array('data' => ''. t('There are currently no applications.') .'', 'colspan' => 7));
}
return theme('table', $form['#header'], $rows) . drupal_render($form);
}
function theme_apply_for_role_status($status) {
$statuses = array(
0 => t('Pending'),
1 => t('Approved'),
2 => t('Denied'),
);
return isset($statuses[$status]) ? $statuses[$status] : t('Unknown status');
}
function apply_for_role_approve_form(&$form_state, $user, $rid) {
$form['uid'] = array(
'#type' => 'value',
'#value' => $user->uid,
);
$form['rid'] = array(
'#type' => 'value',
'#value' => $rid,
);
$roles = user_roles(TRUE);
return confirm_form($form, t('Do you want to approve the application from user %username for role %role', array('%username' => $user->name, '%role' => $roles[$rid])), 'admin/user/apply_for_role', t('The role will be automatically assigned to the user.'), t('Approve'));
}
function apply_for_role_approve_form_submit($form, &$form_state) {
if (apply_for_role_approve_apply($form_state['values']['uid'], $form_state['values']['rid'])) {
drupal_set_message(t('The application was approved.'));
}
else {
drupal_set_message(t('Error approving application. Please try again!'), 'error');
}
cache_clear_all();
$form_state['redirect'] = 'admin/user/apply_for_role';
}
function apply_for_role_deny_form(&$form_state, $user, $rid) {
$form['uid'] = array(
'#type' => 'value',
'#value' => $user->uid,
);
$form['rid'] = array(
'#type' => 'value',
'#value' => $rid,
);
$roles = user_roles(TRUE);
return confirm_form($form, t('Do you want to deny the application from user %username for role %role', array('%username' => $user->name, '%role' => $roles[$rid])), 'admin/user/apply_for_role', t('The role will not be assigned to the user and the user will not be able to apply again.'), t('Deny'));
}
function apply_for_role_deny_form_submit($form, &$form_state) {
if (apply_for_role_deny_apply($form_state['values']['uid'], $form_state['values']['rid'])) {
drupal_set_message(t('The application was denied.'));
}
else {
drupal_set_message(t('Error approving application. Please try again!'), 'error');
}
cache_clear_all();
$form_state['redirect'] = 'admin/user/apply_for_role';
}
function apply_for_role_remove_form(&$form_state, $user, $rid) {
$form['uid'] = array(
'#type' => 'value',
'#value' => $user->uid,
);
$form['rid'] = array(
'#type' => 'value',
'#value' => $rid,
);
$roles = user_roles(TRUE);
return confirm_form($form, t('Do you want to remove the application from user %username for role %role', array('%username' => $user->name, '%role' => isset($roles[$rid]) ? $roles[$rid] : t('Invalid role'))), 'admin/user/apply_for_role', t('The role will be automatically deleted from the user'), t('Delete'));
}
function apply_for_role_remove_form_submit($form, &$form_state) {
if (apply_for_role_remove_apply($form_state['values']['uid'], $form_state['values']['rid'])) {
drupal_set_message(t('The application was deleted.'));
}
else {
drupal_set_message(t('Error deleting application. Please try again!'), 'error');
}
cache_clear_all();
$form_state['redirect'] = 'admin/user/apply_for_role';
}
/**
* User interface
*/
function apply_for_role_apply_form(&$form_state, $user) {
$roles = user_roles(TRUE);
// Figure out all the roles they've applied for.
$applied = array();
$result = db_query("SELECT rid FROM {users_roles_apply} WHERE uid = %d", $user->uid, $rid);
while ($row = db_fetch_object($result)) {
$applied[$row->rid] = isset($roles[$row->rid]) ? $roles[$row->rid] : t('Invalid role');
}
// Figure out which roles are enabled, figure out which roles they have or
// have applied for, then take the remainder.
$enabled = variable_get('users_apply_roles', array());
$used = $user->roles + $applied;
$filter_roles = array_diff($enabled, $used);
if (count($filter_roles)) {
$form['user'] = array(
'#type' => 'value',
'#value' => $user,
);
$form['rid'] = array(
'#type' => variable_get('apply_for_role_multiple', 0) ? 'checkboxes' : 'radios',
'#title' => variable_get('apply_for_role_multiple', 0) ? t('Select the roles you want to apply for') : t('Select the role you want to apply for'),
'#options' => $filter_roles,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Apply')
);
}
else {
drupal_set_message(t('No roles are available at this time.'));
}
return $form;
}
function apply_for_role_apply_form_submit($form, &$form_state) {
apply_for_role_process_apps($form_state['values']['user'], $form_state['values']['rid']);
$form_state['redirect'] = 'user/'. $user->uid;
}
/**
* Implementation of hook_user().
*/
function apply_for_role_user($op, &$edit, &$user, $category = NULL) {
switch ($op) {
case 'register':
// Admin created account aren't processed by the module.
if (user_access('administer users')) {
break;
}
if (variable_get('apply_for_role_register', 0)) {
$filter_roles = array();
foreach (variable_get('users_apply_roles', array()) as $rid => $role) {
if ($rid > 2) {
$filter_roles[$rid] = $role;
}
}
if (count($filter_roles)) {
$form['apply_for_role'] = array(
'#type' => 'fieldset',
'#title' => t('Apply for roles'),
'#collapsible' => FALSE,
);
if (variable_get('apply_for_role_multiple', 0)) {
$form['apply_for_role']['rid'] = array(
'#type' => 'checkboxes',
'#title' => t('Select the role or roles you want to apply for'),
'#options' => $filter_roles,
);
}
else {
array_unshift($filter_roles, '');
$form['apply_for_role']['rid'] = array(
'#type' => 'select',
'#title' => t('Select the role you want to apply for'),
'#options' => $filter_roles,
);
}
return $form;
}
}
break;
case 'insert':
if (variable_get('apply_for_role_register', 0)) {
apply_for_role_process_apps($user, $edit['rid']);
}
break;
case 'delete':
db_query("DELETE FROM {users_roles_apply} WHERE uid = %d", $user->uid);
break;
}
}
/**
* Callbacks
*/
function apply_for_role_user_has_role($uid, $rid) {
if ($uid) {
$user = user_load(array('uid' => $uid));
if ($user->uid && $user->roles[$rid]) {
return TRUE;
}
}
return FALSE;
}
function apply_for_role_add_apply($uid, $rid) {
if (!apply_for_role_user_has_role($uid, $rid)) {
// Check if the user has already applied for this role
if (!db_result(db_query("SELECT uid, rid FROM {users_roles_apply} WHERE uid = %d AND rid = %d", $uid, $rid))) {
db_query("INSERT INTO {users_roles_apply} (uid, rid, approved, apply_date) VALUES (%d, %d, 0, %d)", $uid, $rid, time());
return TRUE;
}
}
}
function apply_for_role_approve_apply($uid, $rid) {
if (!apply_for_role_user_has_role($uid, $rid)) {
if ($row = db_fetch_object(db_query("SELECT uid, rid, approved FROM {users_roles_apply} WHERE uid = %d AND rid = %d", $uid, $rid))) {
if ($row->approved == 0) {
apply_for_role_add_role($uid, $rid);
$row->approve_date = time();
$row->approved = 1;
return drupal_write_record('users_roles_apply', $row, array('uid', 'rid'));
}
}
}
}
function apply_for_role_deny_apply($uid, $rid) {
if (!apply_for_role_user_has_role($uid, $rid)) {
if ($row = db_fetch_object(db_query("SELECT uid, rid, approved FROM {users_roles_apply} WHERE uid = %d AND rid = %d", $uid, $rid))) {
if ($row->approved == 0) {
$row->approve_date = time();
$row->approved = 2;
return drupal_write_record('users_roles_apply', $row, array('uid', 'rid'));
}
}
}
}
function apply_for_role_remove_apply($uid, $rid) {
$result = db_query("SELECT uid, rid, approved FROM {users_roles_apply} WHERE uid = %d AND rid = %d", $uid, $rid);
if (!empty($result)) {
apply_for_role_delete_role($uid, $rid);
db_query("DELETE FROM {users_roles_apply} WHERE uid = %d AND rid = %d", $uid, $rid);
return TRUE;
}
}
function apply_for_role_add_role($uid, $rid) {
if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $uid, $rid);
}
}
function apply_for_role_delete_role($uid, $rid) {
if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
db_query('DELETE FROM {users_roles} WHERE uid = %d AND rid = %d', $uid, $rid);
}
}
/**
* Process an application and store it for admin review.
*
* @param $user User object.
* @param $apps Mixed, either a role id or an array keyed by role id.
*/
function apply_for_role_process_apps($user, $apps) {
$roles = user_roles(TRUE);
// They can hand in either an array keyed by role id or single role id.
// Ensure we've got an array keyed by role id with the name as the value.
if (is_array($apps)) {
// Filter out any thing with empty role names. And use the official role
// name.
$apps = array_intersect_key($roles, array_filter($apps));
}
else {
$apps = array($apps => $roles[$apps]);
}
$received = array();
$not_received = array();
foreach ($apps as $rid => $role) {
if (apply_for_role_add_apply($user->uid, $rid)) {
$received[] = $role;
}
else {
$not_received[] = $role;
}
}
if (!empty($received)) {
drupal_set_message(t('%message %roles', array('%message' => format_plural(count($received), t('Your application was received for the following role:'), t('Your applications were received for the following roles:')), '%roles' => implode(', ', $received))));
}
if (!empty($not_received)) {
drupal_set_message(t('%message %roles', array('%message' => format_plural(count($not_received), t('There was a problem processing your application for the following role:'), t('There was a problem processing your applications for the following roles:')), '%roles' => implode(', ', $not_received))), 'error');
}
}