diff --git a/autoassignrole.admin.inc b/autoassignrole.admin.inc index 330ba83..e3e3719 100644 --- a/autoassignrole.admin.inc +++ b/autoassignrole.admin.inc @@ -174,3 +174,316 @@ function autoassignrole_user_settings() { return system_settings_form($form); } + +/* + * Implements hook_form. + * + * Form to edit or add role-specific pages. + */ +function autoassignrole_page_form($form, &$form_state, $op = 'add', $id = 0) { + $roles = user_roles(TRUE); + unset($roles[DRUPAL_AUTHENTICATED_RID]); + + $form = array(); + + switch($op) { + case "add": + $title = t('Add a new role page'); + $submit_value = t('Add'); + break; + + case "edit": + $title = t('Edit role page'); + $submit_value = t('Save'); + break; + } + + $form['rid_page'] = array( + '#type' => 'fieldset', + '#title' => $title, + ); + + $form['rid_page']['op_term'] = array( + '#type' => 'hidden', + '#value' => $op, + ); + + if ($op == "edit") { + $form['rid_page']['id'] = array( + '#type' => 'hidden', + '#value' => $id, + ); + if ($id > 0) { + $page = autoassignrole_get_page($id); + } + } + + $form['rid_page']['roles'] = array( + '#type' => 'checkboxes', + '#title' => t('Role'), + '#description' => t('Select the roles this page will assign'), + '#options' => $roles, + '#required' => TRUE, + '#default_value' => isset($page->rids) ? unserialize($page->rids) : array(), + ); + + $form['rid_page']['title'] = array( + '#type' => 'textfield', + '#title' => t('Page Title'), + '#description' => t('Enter the title of the page'), + '#size' => 60, + '#required' => TRUE, + '#default_value' => isset($page->title) ? $page->title : "", + ); + + $form['rid_page']['path'] = array( + '#type' => 'textfield', + '#title' => t('Page Path'), + '#description' => t('Enter the path for the registration page.'), + '#size' => 60, + '#required' => TRUE, + '#default_value' => isset($page->path) ? $page->path : "", + ); + + $form['rid_page']['menu'] = array( + '#type' => 'select', + '#title' => t('Menu'), + '#description' => t('Which parent menu item should these pages appear under? This will only apply if you choose the "Standard" display option below.'), + '#options' => menu_get_menus(), + '#default_value' => isset($page->menu) ? $page->menu : "", + ); + + $form['rid_page']['display'] = array( + '#type' => 'select', + '#title' => t('Display type'), + '#description' => t('Choose the way you would like these pages to be displayed. Standard is equivalent to the core Drupal log in form, with tabs along the top, while individual is separate pages without tabs.'), + '#options' => array( + 0 => t('Standard'), + 1 => t('Individual'), + ), + '#default_value' => isset($page->display) ? $page->display : "", + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => $submit_value, + ); + + return $form; +} + +/* + * Implements hook_form_validate. + * + * Check path to see if page already exists. + */ +function autoassignrole_page_form_validate($form_id, &$form_state) { + $roles = $form_state['values']['roles']; + $title = $form_state['values']['title']; + $path = $form_state['values']['path']; + + if ($path) { + if (preg_match('/[^A-Za-z0-9\/_-]+/', $path) || strpos(trim($path), '/') === 0) { + form_set_error('path', '\''. check_plain($path) .'\' '. t('is not a valid path')); + } + else { + $query = db_select('menu_links', 'm') + ->fields('m', array('mlid')) + ->condition('link_path', $path, 'like'); + $count = $query->countQuery()->execute()->fetchField(); + if (drupal_lookup_path('source', $path) || $count > 0) { + // the menu item exists so need to check if the path has + // something other than autoassign_role_path registered + // otherwise throw an error + $menu_item = menu_get_item($path); + if (!isset($menu_item['page_callback']) && $menu_item['page_callback'] != 'autoassignrole_path') { + form_set_error('path', '\''. check_plain($path) .'\' '. t('is already in use as a path')); + } + } + } + } +} + +/* + * Implements hook_form_submit. + */ +function autoassignrole_page_form_submit($form_id, &$form_state) { + $page = array( + 'rids' => serialize($form_state['values']['roles']), + 'path' => $form_state['values']['path'], + 'menu' => $form_state['values']['menu'], + 'title' => $form_state['values']['title'], + 'display' => $form_state['values']['display'], + ); + + $return = FALSE; + $op = $form_state['values']['op_term']; + switch ($op) { + case "add": + $return = autoassignrole_add_page($page); + $operation = "Created"; + break; + + case "edit": + $id = $form_state['values']['id']; + $return = autoassignrole_update_page($page, $id); + $operation = "Updated"; + case "edit": + $id = $form_state['values']['id']; + $return = autoassignrole_update_page($page, $id); + $operation = "Updated"; + break; + } + + if ($return) { + menu_rebuild(); + drupal_set_message(t('Successfuly @operation Page @page', array('@operation' => $operation, '@page' => $page['title']))); + drupal_goto('admin/config/people/autoassignrole/pages'); + } + else { + drupal_set_message(t('Oh dear. Looks like the evil space monkeys messed something up again'), 'error'); + } +} + +/* + * Function to add role-specific page. + * + * @return + * Return boolean - true if succesful. + */ +function autoassignrole_add_page($page) { + $return_value = NULL; + try { + $return_value = db_insert('autoassignrole_page')->fields($page)->execute(); + } + catch (Exception $e) { + drupal_set_message(t('db_insert failed. Message = %message, query = %query', array('%message' => $e->getMessage(), '%query' => $e->query_string)), 'error'); + } + return $return_value; +} + +/* + * Fuction to update existing role-specific page. + * + * @return + * Return boolean - true if succesful. + */ +function autoassignrole_update_page($page, $id) { + $return_value = NULL; + try { + $return_value = db_update('autoassignrole_page') + ->fields($page) + ->condition('rid_page_id', $id) + ->execute(); + } + catch (Exception $e) { + drupal_set_message(t('db_update failed. Message = %message, query = %query', array('%message' => $e->getMessage(), '%query' => $e->query_string)), 'error'); + } + return $return_value; +} + +/* + * Function to delete role-specific page. + */ +function autoassignrole_delete_page($id) { + $query = db_delete('autoassignrole_page') + ->condition('rid_page_id', $id) + ->execute(); + menu_rebuild(); + drupal_set_message(t('Successfully deleted page')); + drupal_goto('admin/config/people/autoassignrole/pages/'); +} + +/* + * Function to get role-specific page details. + * + * @return + * Returns object with all page details. + */ +function autoassignrole_get_page($id) { + $query = db_select('autoassignrole_page', 'page') + ->fields('page', array( + 'rids', + 'path', + 'menu', + 'title', + 'display', + )) + ->condition('rid_page_id', $id, '='); + + return $query->execute()->fetchObject(); +} + +/* + * Function to display list of role-specific pages. + * + * @return + * Returns a build array. + */ +function autoassignrole_list_pages() { + $header = array( + array('data' => 'Title', 'field' => 'title', 'sort' => 'asc'), + array('data' => 'Roles', 'field' => 'rids'), + array('data' => 'Path', 'field' => 'path'), + array('data' => 'Operations'), + ); + + $query = db_select('autoassignrole_page', 'p') + ->extend('PagerDefault') + ->limit(10) + ->extend('TableSort') + ->orderByHeader($header) + ->fields ('p', array ( + 'rid_page_id', + 'rids', + 'title', + 'path', + ) + ); + + $results = $query->execute(); + + $user_roles = user_roles(TRUE); + $rows = array(); + foreach ($results as $page) { + $rids = unserialize($page->rids); + $roles = ""; + $count = 0; + foreach ($rids as $rid) { + if (!empty($rid) && array_key_exists($rid, $user_roles)) { + if ($count != 0) { + $roles .= ", "; + } + $roles .= $user_roles[$rid]; + $count++; + } + } + $edit = l('Edit', 'admin/config/people/autoassignrole/pages/edit/' . $page->rid_page_id); + $delete = l('Delete', 'admin/config/people/autoassignrole/pages/delete/' . $page->rid_page_id); + $links = $edit . " | " . $delete; + $rows[] = array( + 'data' => array( + $page->title, + $roles, + $page->path, + $links, + ) + ); + } + $html = theme('table', + array( + 'header' => $header, + 'rows'=>$rows, + 'sticky' => TRUE, + 'empty' => 'No Auto Assign pages created...', + ) + ); + + $html .= theme('pager', + array( + 'tags' => array() + ) + ); + + return ($html); +} diff --git a/autoassignrole.install b/autoassignrole.install index 040f77c..d5c6eb4 100644 --- a/autoassignrole.install +++ b/autoassignrole.install @@ -5,3 +5,60 @@ * * Installation related functionality for the auto assign role module. */ + + +/** + * Implements hook_schema(). + * + * autoassignrole_page holds information on pages generated to sign users up with a particular role (as opposed to them choosing one) + */ + +function autoassignrole_install() { +} + +function autoassignrole_uninstall() { +} + +function autoassignrole_schema() { + $schema['autoassignrole_page'] = array( + 'description' => t('Stores autoassignrole page information'), + 'fields' => array( + 'rid_page_id' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'description' => t('The unique indentifier for this role page'), + ), + 'rids' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'description' => t('The role IDs for this page'), + ), + 'path' => array( + 'type' => 'text', + 'length' => 255, + 'not null' => TRUE, + 'description' => t('The path for this page'), + ), + 'menu' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'description' => t('The default parent menu for this menu item'), + ), + 'title' => array( + 'type' => 'text', + 'not null' => TRUE, + 'description' => t('The description for this page'), + ), + 'display' => array( + 'type' => 'int', + 'not null' => TRUE, + 'description' => t('The display type for this page'), + ), + ), + 'primary key' => array('rid_page_id'), + ); + + return $schema; +} diff --git a/autoassignrole.module b/autoassignrole.module index 30c43e4..d3e43d2 100644 --- a/autoassignrole.module +++ b/autoassignrole.module @@ -59,17 +59,132 @@ function autoassignrole_menu() { 'page arguments' => array('autoassignrole_user_settings'), 'file' => 'autoassignrole.admin.inc', ); + $items['admin/config/people/autoassignrole/pages'] = array( + 'title' => 'Per Role Pages', + 'description' => 'Configure individual pages to allow user to sign up for a particular role', + 'access arguments' => array('administer autoassignrole'), + 'page callback' => 'autoassignrole_list_pages', + 'file' => 'autoassignrole.admin.inc', + ); + $items['admin/config/people/autoassignrole/pages/add'] = array( + 'title' => 'Add Auto Assign Role Page', + 'access arguments' => array('administer autoassignrole'), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('autoassignrole_page_form', 'add'), + 'type' => MENU_LOCAL_ACTION, + 'file' => 'autoassignrole.admin.inc', + ); + $items['admin/config/people/autoassignrole/pages/edit/%'] = array( + 'title' => 'Edit Auto Assign Role Page', + 'access arguments' => array('administer autoassignrole'), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('autoassignrole_page_form', 'edit', 6), + 'type' => MENU_CALLBACK, + 'file' => 'autoassignrole.admin.inc', + ); + $items['admin/config/people/autoassignrole/pages/delete/%'] = array( + 'title' => 'Delete Auto Assign Role Page', + 'access arguments' => array('administer autoassignrole'), + 'page callback' => 'autoassignrole_delete_page', + 'page arguments' => array(6), + 'type' => MENU_CALLBACK, + 'file' => 'autoassignrole.admin.inc', + ); + + $pages = autoassignrole_get_pages(); + foreach ($pages as $page) { + $rids = unserialize($page->rids); + switch ($page->display) { + case 0: + $items[$page->path] = array( + 'title' => check_plain($page->title), + 'page arguments' => array($rids), + 'page callback' => 'autoassignrole_register', + 'access callback' => 'user_register_access', + 'file' => 'autoassignrole.paths.inc', + 'type' => MENU_NORMAL_ITEM, + 'menu_name' => $page->menu, + ); + $items[$page->path . '/register'] = array( + 'title' => t('Register'), + 'page arguments' => array($rids), + 'page callback' => 'autoassignrole_register', + 'access callback' => 'user_register_access', + 'file' => 'autoassignrole.paths.inc', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + $items[$page->path . '/login'] = array( + 'title' => t('Log In'), + 'page callback' => 'autoassignrole_login', + 'access callback' => 'user_is_anonymous', + 'file' => 'autoassignrole.paths.inc', + 'type' => MENU_LOCAL_TASK, + ); + $items[$page->path . '/password'] = array( + 'title' => t('Request New Password'), + 'page callback' => 'autoassignrole_password', + 'access callback' => 'user_is_anonymous', + 'file' => 'autoassignrole.paths.inc', + 'type' => MENU_LOCAL_TASK, + ); + break; + + case 1: + $items[$page->path] = array( + 'title' => check_plain($page->title), + 'page arguments' => array($rids), + 'page callback' => 'autoassignrole_register', + 'access callback' => 'user_register_access', + 'file' => 'autoassignrole.paths.inc', + 'type' => MENU_CALLBACK, + ); + $items[$page->path . '/register'] = array( + 'title' => t('Register'), + 'page arguments' => array($rids), + 'page callback' => 'autoassignrole_register', + 'access callback' => 'user_register_access', + 'file' => 'autoassignrole.paths.inc', + 'type' => MENU_CALLBACK, + ); + $items[$page->path . '/login'] = array( + 'title' => t('Log In'), + 'page callback' => 'autoassignrole_login', + 'access callback' => 'user_is_anonymous', + 'file' => 'autoassignrole.paths.inc', + 'type' => MENU_CALLBACK, + ); + $items[$page->path . '/password'] = array( + 'title' => t('Request New Password'), + 'page callback' => 'autoassignrole_password', + 'access callback' => 'user_is_anonymous', + 'file' => 'autoassignrole.paths.inc', + 'type' => MENU_CALLBACK, + ); + break; + } + } return $items; } +/* + * Finds any role ids attached to current page, if any. + */ +function autoassignrole_get_active_path_rid() { + $item = menu_get_item(); + if ($item['page_callback'] == 'autoassignrole_register') { + return $item['page_arguments'][0]; + } + return FALSE; +} + /** * Implements hook_user_presave(). */ function autoassignrole_user_presave(&$edit, $account, $category) { // Use case http://drupal.org/node/971622 // Make sure we only assign roles automatically when enabled to do so. - if (variable_get('autoassignrole_auto_active', 0) || variable_get("autoassignrole_user_active", 0)) { + if (variable_get('autoassignrole_auto_active', 0) || variable_get("autoassignrole_user_active", 0) || autoassignrole_get_active_path_rid()) { // Use case http://drupal.org/node/944864 // Only assign roles if this is a new account. if (isset($account->is_new) && !empty($account->is_new)) { @@ -91,6 +206,12 @@ function autoassignrole_user_presave(&$edit, $account, $category) { $roles_to_add += array_intersect_key($user_roles, array_filter($edit['user_roles'])); } + // Add page-specific roles. + $page_rids = autoassignrole_get_active_path_rid(); + if ($page_rids) { + $roles_to_add = array_intersect_key($user_roles, array_filter($page_rids)); + } + // Make sure the roles key exists. if (!isset($edit['roles'])) { $edit['roles'] = array(); @@ -149,3 +270,23 @@ function autoassignrole_form_user_register_form_alter(&$form, &$form_state) { } } } + +/* + * Function to retrieve all role-specific pages. + * + * @return + * Returns an array of page objects. + */ +function autoassignrole_get_pages() { + $query = db_select('autoassignrole_page', 'p') + ->fields('p', array( + 'rids', + 'path', + 'title', + 'menu', + 'display', + ) + ); + + return $query->execute(); +} diff --git a/autoassignrole.paths.inc b/autoassignrole.paths.inc new file mode 100644 index 0000000..54f37a2 --- /dev/null +++ b/autoassignrole.paths.inc @@ -0,0 +1,46 @@ +