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'); } }