diff --git a/autoassignrole.admin.inc b/autoassignrole.admin.inc index 83a78cd..6956ffb 100644 --- a/autoassignrole.admin.inc +++ b/autoassignrole.admin.inc @@ -6,28 +6,6 @@ * Administrative functionality for auto assign role. */ - -/** - * Provide a single block from the administration menu as a page. - * This function is often a destination for these blocks. - * For example, 'admin/structure/types' needs to have a destination to be valid - * in the Drupal menu system, but too much information there might be - * hidden, so we supply the contents of the block. - * - * @return - * The output HTML. - */ -function autoassignrole_admin_block_page() { - $item = menu_get_item(); - if ($content = system_admin_menu_block($item)) { - $output = theme('admin_block_content', array('content' => $content)); - } - else { - $output = t('You do not have any administrative items.'); - } - return $output; -} - /** * Form builder; The settings form for automatic role assignment. * @@ -167,3 +145,309 @@ 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 Drupal path for the registration page for this role. This is a relative path based on your Drupal installation.'), + '#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/ registration form, with tabs along the top.
Individual is a separate page without tabs.'), + '#options' => array( + AUTOASSIGNROLE_PAGE_DISPLAY_STANDARD => t('Standard'), + AUTOASSIGNROLE_PAGE_DISPLAY_INDIVIDUAL => 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) { + $path = $form_state['values']['path']; + + // @todo need to check if the path already exists. + 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'; + 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('Unfortunately there has been an error and this page could not be %op', array('%op' => drupal_strtolower($operation))), 'error'); + } +} + +/** + * Function to add role-specific page. + * + * @param array $page + * The details of the page to be added. + * + * @return + * Return boolean - true if successful. + */ +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; +} + +/** + * Function to update existing role-specific page. + * + * @param array $page + * The details of the page to be added. + * @param int $id + * The id of the page to be updated. + * + * @return + * Return boolean - true if successful. + */ +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_page_delete_confirm($form, &$form_state, $pageId) { + $page = autoassignrole_get_page($pageId); + $form['page_id'] = array( + '#type' => 'value', + '#value' => $pageId, + ); + + return confirm_form($form, t('Are you sure you want to delete the page %name ?', array('%name' => $page->title)), 'admin/config/people/autoassignrole/pages', t('This action cannot be undone.'), t('Delete')); +} + +/** + * Form submit handler for autoassignrole_page_delete_confirm(). + */ +function autoassignrole_page_delete_confirm_submit($form, &$form_state) { + db_delete('autoassignrole_page') + ->condition('rid_page_id', (int) $form_state['values']['page_id']) + ->execute(); + menu_rebuild(); + drupal_set_message(t('Successfully deleted page')); + $form_state['redirect'] = 'admin/config/people/autoassignrole/pages'; +} + +/** + * 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 b723c83..0bc53dc 100644 --- a/autoassignrole.install +++ b/autoassignrole.install @@ -31,6 +31,9 @@ function autoassignrole_uninstall() { // D6 installation. variable_del('autoassignrole_node_user_register'); variable_del('autoassignrole_page_active'); + + // Remove the autoassignrole_page table. + db_drop_table('autoassignrole_page'); } /** @@ -91,3 +94,50 @@ function autoassignrole_update_7100() { drupal_set_message(t('AutoAssignRole: no need to upgrade existing D7 sites.')); } } + +/** + * Add the assign to page table. + */ +function autoassignrole_update_7101() { + $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 identifier 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'), + ); + + db_create_table('autoassignrole_page', $schema['autoassignrole_page']); +} \ No newline at end of file diff --git a/autoassignrole.module b/autoassignrole.module index f5aafc3..1bdeac1 100644 --- a/autoassignrole.module +++ b/autoassignrole.module @@ -17,6 +17,13 @@ define('AUTOASSIGNROLE_ELEMENT_SELECT', 1); // Says to use element of type select for checkbox selection define('AUTOASSIGNROLE_ELEMENT_CHECKBOX', 2); + +// Sets the page display for standard. +define('AUTOASSIGNROLE_PAGE_DISPLAY_STANDARD', 0); + +// Sets the page display for individual. +define('AUTOASSIGNROLE_PAGE_DISPLAY_INDIVIDUAL', 1); + /** * Implements hook_permission(). */ @@ -40,15 +47,15 @@ function autoassignrole_menu() { 'title' => 'Auto assign role', 'description' => 'Configure auto role assignment.', 'access arguments' => array('administer autoassignrole'), - 'page callback' => 'autoassignrole_admin_block_page', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('autoassignrole_auto_settings'), 'file' => 'autoassignrole.admin.inc', ); - $items['admin/config/people/autoassignrole/auto'] = array( + $items['admin/config/people/autoassignrole/autoassignrole'] = array( 'title' => 'Automatic', 'description' => 'Configure which role(s) are automatically assigned on user creation.', 'access arguments' => array('administer autoassignrole'), - 'page callback' => 'drupal_get_form', - 'page arguments' => array('autoassignrole_auto_settings'), + 'type' => MENU_DEFAULT_LOCAL_TASK, 'file' => 'autoassignrole.admin.inc', ); $items['admin/config/people/autoassignrole/user'] = array( @@ -57,20 +64,138 @@ function autoassignrole_menu() { 'access arguments' => array('administer autoassignrole'), 'page callback' => 'drupal_get_form', 'page arguments' => array('autoassignrole_user_settings'), + 'type' => MENU_LOCAL_TASK, + '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', + 'type' => MENU_LOCAL_TASK, + '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' => 'drupal_get_form', + 'page arguments' => array('autoassignrole_page_delete_confirm', 6), + 'type' => MENU_CALLBACK, + 'file' => 'autoassignrole.admin.inc', + ); + + $pages = autoassignrole_get_pages(); + foreach ($pages as $page) { + $rids = unserialize($page->rids); + switch ($page->display) { + case AUTOASSIGNROLE_PAGE_DISPLAY_STANDARD: + $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 AUTOASSIGNROLE_PAGE_DISPLAY_INDIVIDUAL: + $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) - || (variable_get('autoassignrole_admin_active', 0) && user_access('administer users'))) { + || (variable_get('autoassignrole_admin_active', 0) && user_access('administer users')) + || 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)) { @@ -79,7 +204,7 @@ function autoassignrole_user_presave(&$edit, $account, $category) { $roles_to_add = array(); // Add in automatic roles. - if ((variable_get('autoassignrole_auto_active', 0) && !user_access('administer users')) + if (variable_get('autoassignrole_auto_active', 0) || (variable_get('autoassignrole_admin_active', 0) && user_access('administer users'))) { $roles_to_add += array_intersect_key($user_roles, array_filter(variable_get('autoassignrole_auto_roles', array()))); } @@ -93,6 +218,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(); @@ -151,3 +282,46 @@ function autoassignrole_form_user_register_form_alter(&$form, &$form_state) { } } } + +/** + * Function to retrieve all role-specific pages. + * + * @return SelectQuery + * An array of page objects. + */ +function autoassignrole_get_pages() { + $query = _autoasignrole_get_page_query(); + return $query->execute(); +} + +/** + * Function to get role-specific page details. + * + * @param int $id + * The id of the page to be updated. + * + * @return SelectQuery + * A query object with all page details. + */ +function autoassignrole_get_page($id) { + $query = _autoasignrole_get_page_query(); + $query->condition('rid_page_id', $id, '='); + return $query->execute()->fetchObject(); +} + +/** + * Helper method for getting the page query object. + * + * @return SelectQuery + * The query object. + */ +function _autoasignrole_get_page_query() { + return db_select('autoassignrole_page', 'p') + ->fields('p', array( + 'rids', + 'path', + 'title', + 'menu', + 'display', + )); +} \ No newline at end of file diff --git a/autoassignrole.paths.inc b/autoassignrole.paths.inc new file mode 100644 index 0000000..4dea791 --- /dev/null +++ b/autoassignrole.paths.inc @@ -0,0 +1,53 @@ +