You are here

multiple_registration.module in Multiple Registration 7

Add ability to create several registration pages.

File

multiple_registration.module
View source
<?php

/**
 * @file
 * Add ability to create several registration pages.
 */
define('MULTIPLE_REGISTRATION_SIGNUP_PATH_PATTERN', 'user/signup/');
define('MULTIPLE_REGISTRATION_GENERAL_REGISTRATION_ID', 100);

/**
 * Implements hook_menu().
 */
function multiple_registration_menu() {
  $items = array();
  $items['admin/config/people/multiple_registration'] = array(
    'title' => 'Multiple registrations pages',
    'description' => 'Multiple registration configuration',
    'page callback' => 'multiple_registration_settings_form',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer multiple_registration',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/config/people/multiple_registration/%/add'] = array(
    'title' => 'Create new registration page',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'multiple_registration_create_registration_form',
      4,
    ),
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer multiple_registration',
    ),
    'type' => MENU_CALLBACK,
  );
  $items['admin/config/people/multiple_registration/%/remove'] = array(
    'title' => 'Remove registration page',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'multiple_registration_remove_registration_form',
      4,
    ),
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer multiple_registration',
    ),
    'type' => MENU_CALLBACK,
  );
  $items['admin/config/people/multiple_registration/default_form'] = array(
    'title' => 'Manage default registration form state',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'multiple_registration_default_registration_form',
    ),
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer multiple_registration',
    ),
    'type' => MENU_CALLBACK,
  );
  if ($registration_pages = _multiple_registration_get_registration_pages()) {
    $user_roles = user_roles();
    foreach ($registration_pages as $rid => $path) {
      $items[$path] = array(
        'title' => 'Create new @role account',
        'title arguments' => array(
          '@role' => $user_roles[$rid],
        ),
        'page callback' => 'drupal_get_form',
        'page arguments' => array(
          'user_register_form',
        ),
        'access callback' => 'user_register_access',
        'type' => MENU_LOCAL_TASK,
      );
    }
  }
  return $items;
}

/**
 * Implements hook_menu_alter().
 *
 * @param $items
 */
function multiple_registration_menu_alter(&$items) {
  $default_registration_form_status = variable_get('disable_default_registration_form', FALSE);
  if ($default_registration_form_status !== FALSE && $default_registration_form_status !== 0) {

    // Disable the user/register page.
    $items['user/register']['access callback'] = FALSE;
  }
}

/**
 * Implements hook_permission().
 */
function multiple_registration_permission() {
  return array(
    'administer multiple_registration' => array(
      'title' => t('Administer multiple registration'),
      'description' => t('Configure multiple registration module'),
    ),
  );
}

/**
 * Implements hook_theme_registry_alter().
 *
 * Altering user_admin_roles theme function.
 * We need it for customization user roles table.
 */
function multiple_registration_theme_registry_alter(&$theme_registry) {
  $theme_registry['user_admin_roles']['function'] = 'multiple_registration_user_admin_roles';
}

/**
 * Returns HTML for the role order and new role form.
 *
 * @param array $variables
 *   An associative array containing:
 *   - form: A render element representing the form.
 *
 * @return string
 * @throws Exception
 * @ingroup themeable
 */
function multiple_registration_user_admin_roles(array $variables) {
  $form = $variables['form'];
  $header = array(
    t('Name'),
    t('Weight'),
    array(
      'data' => t('Operations'),
      'colspan' => 3,
    ),
  );
  foreach (element_children($form['roles']) as $rid) {
    $name = $form['roles'][$rid]['#role']->name;
    $row = array();
    if (in_array($rid, array(
      DRUPAL_ANONYMOUS_RID,
      DRUPAL_AUTHENTICATED_RID,
    ))) {
      $row[] = t('@name <em>(locked)</em>', array(
        '@name' => $name,
      ));
      $row[] = drupal_render($form['roles'][$rid]['weight']);
      $row[] = '';
      $row[] = l(t('edit permissions'), 'admin/people/permissions/' . $rid);
      $row[] = '';
    }
    else {
      $row[] = check_plain($name);
      $row[] = drupal_render($form['roles'][$rid]['weight']);
      $row[] = l(t('edit role'), 'admin/people/permissions/roles/edit/' . $rid);
      $row[] = l(t('edit permissions'), 'admin/people/permissions/' . $rid);
      if ($rid != variable_get('user_admin_role')) {
        if (!variable_get('multiple_registration_url_' . $rid, '')) {
          $row[] = l(t('add own registration page'), 'admin/config/people/multiple_registration/' . $rid . '/add', array(
            'query' => array(
              'destination' => current_path(),
            ),
          ));
        }
        else {
          $row[] = l(t('remove own registration page'), 'admin/config/people/multiple_registration/' . $rid . '/remove', array(
            'query' => array(
              'destination' => current_path(),
            ),
          ));
        }
      }
      else {
        $row[] = '';
      }
    }
    $rows[] = array(
      'data' => $row,
      'class' => array(
        'draggable',
      ),
    );
  }
  $rows[] = array(
    array(
      'data' => drupal_render($form['name']) . drupal_render($form['add']),
      'colspan' => 4,
      'class' => 'edit-name',
    ),
  );
  drupal_add_tabledrag('user-roles', 'order', 'sibling', 'role-weight');
  $output = theme('table', array(
    'header' => $header,
    'rows' => $rows,
    'attributes' => array(
      'id' => 'user-roles',
    ),
  ));
  $output .= drupal_render_children($form);
  return $output;
}

/**
 * Form for managing all created registration pages.
 */
function multiple_registration_settings_form() {
  $register_pages = _multiple_registration_get_registration_pages();
  $roles = user_roles();
  if ($register_pages) {
    $rids = array_keys($register_pages);
    foreach ($rids as $rid) {
      $row = array();
      $row[] = $roles[$rid];
      $row[] = variable_get('multiple_registration_path_' . $rid, '');
      $row[] = l(t('Edit'), 'admin/config/people/multiple_registration/' . $rid . '/add', array(
        'query' => array(
          'destination' => current_path(),
        ),
      ));
      $row[] = l(t('Remove'), 'admin/config/people/multiple_registration/' . $rid . '/remove', array(
        'query' => array(
          'destination' => current_path(),
        ),
      ));
      $rows[] = array(
        'data' => $row,
      );
    }
    $header = array(
      t('Role'),
      t('Registration page path'),
      array(
        'data' => t('Operations'),
        'colspan' => 2,
      ),
    );
    $output = array(
      '#theme' => 'table',
      '#header' => $header,
      '#rows' => $rows,
      '#attributes' => array(
        'id' => 'user-roles-reg-pages',
      ),
    );
  }
  else {
    $output = array(
      '#markup' => t('There are no additional registration pages created yet. You can add new pages !here', array(
        '!here' => l(t('here'), 'admin/people/permissions/roles'),
      )),
    );
  }
  $output['#suffix'] = '<p>' . l(t('Go to Roles managing page '), 'admin/people/permissions/roles') . '<p></p>' . l(t(' Manage default registration form status'), 'admin/config/people/multiple_registration/default_form') . '</p>';
  $form['user_register_pages'] = $output;
  return $form;
}

/**
 * Form for creating new registration page.
 */
function multiple_registration_create_registration_form($form, &$form_state, $rid) {
  if (!isset($rid) || !is_numeric($rid)) {
    return FALSE;
  }
  $roles = user_roles();
  if (!isset($roles[$rid])) {
    return FALSE;
  }
  $form['rid'] = array(
    '#type' => 'value',
    '#value' => $rid,
  );
  $form['multiple_registration_path_' . $rid] = array(
    '#type' => 'textfield',
    '#title' => t('@role Registration page path', array(
      '@role' => $roles[$rid],
    )),
    '#description' => t('Path for registration page.'),
    '#default_value' => variable_get('multiple_registration_path_' . $rid, ''),
    '#required' => TRUE,
  );
  $form['multiple_registration_url_' . $rid] = array(
    '#type' => 'value',
    '#value' => MULTIPLE_REGISTRATION_SIGNUP_PATH_PATTERN . $rid,
  );
  $form['#submit'][] = 'multiple_registration_create_registration_form_submit';
  return system_settings_form($form);
}

/**
 * Form for removing registration page.
 */
function multiple_registration_remove_registration_form($form, &$form_state, $rid) {
  if (!isset($rid) || !is_numeric($rid)) {
    return FALSE;
  }
  $roles = user_roles();
  if (!isset($roles[$rid])) {
    return FALSE;
  }
  $form['rid'] = array(
    '#type' => 'value',
    '#value' => $rid,
  );
  $form['message'] = array(
    '#markup' => '<p>' . t('Are you sure want to delete registration page for !rol role?', array(
      '!rol' => '<strong>' . $roles[$rid] . '</strong>',
    )) . '</p>',
  );
  $form['dont_remove'] = array(
    '#type' => 'submit',
    '#value' => t('No'),
  );
  $form['remove'] = array(
    '#type' => 'submit',
    '#value' => t('Yes'),
  );
  $form['#submit'][] = 'multiple_registration_remove_registration_form_submit';
  return $form;
}

/**
 * Submit function for multiple_registration_create_registration_form.
 */
function multiple_registration_create_registration_form_submit($form, &$form_state) {
  $rid = $form_state['values']['rid'];

  // Before creating new alias, delete old aliases.
  _multiple_registration_remove_page_alias($rid);
  $params = array(
    'source' => $form_state['values']['multiple_registration_url_' . $rid],
    'alias' => $form_state['values']['multiple_registration_path_' . $rid],
  );
  path_save($params);
  multiple_registration_cc_flag();
}

/**
 * Sets flag to clear cache.
 */
function multiple_registration_cc_flag() {
  $clear_cache =& drupal_static('multiple_registration_cc');
  if (!isset($clear_cache)) {
    $clear_cache = 1;
  }
}

/**
 * Implements hook_exit().
 */
function multiple_registration_exit() {
  $clear_cache =& drupal_static('multiple_registration_cc');
  if ($clear_cache) {
    drupal_flush_all_caches();
  }
}

/**
 * Submit function for multiple_registration_remove_registration_form.
 */
function multiple_registration_remove_registration_form_submit($form, &$form_state) {
  switch ($form_state['clicked_button']['#id']) {
    case 'edit-remove':
      $rid = $form_state['values']['rid'];
      if ($rid) {
        _multiple_registration_remove_page($rid);
      }
      break;
    default:
      $form_state['redirect'] = array(
        'admin/people/permissions/roles',
      );
  }
}

/**
 * Get all role ids for whom registration forms was created.
 *
 * @return mixed
 *   If registration forms exists, array of paths.
 *   In other situation - FALSE.
 */
function _multiple_registration_get_registration_pages() {
  $roles = user_roles();
  ksort($roles);

  // Include only custom created roles.
  $allowed_roles = array_keys(array_slice($roles, variable_get('user_admin_role'), NULL, TRUE));
  if ($allowed_roles) {
    $reg_forms = array();
    foreach ($allowed_roles as $rid) {
      if ($url = variable_get('multiple_registration_url_' . $rid, '')) {
        $reg_forms[$rid] = $url;
      }
    }
    return $reg_forms;
  }
  return FALSE;
}

/**
 * Removes url aliases.
 *
 * @param int $rid
 *   User role id.
 */
function _multiple_registration_remove_page_alias($rid) {
  $source = variable_get('multiple_registration_url_' . $rid, '');
  if ($source) {
    db_delete('url_alias')
      ->condition('source', $source)
      ->execute();
  }
  else {
    return FALSE;
  }
}

/**
 * Removes registering page for role.
 *
 * @param int $rid
 *   User role Id.
 */
function _multiple_registration_remove_page($rid) {
  if (variable_get('multiple_registration_url_' . $rid, '')) {
    _multiple_registration_remove_page_alias($rid);
    variable_del('multiple_registration_path_' . $rid);
    variable_del('multiple_registration_url_' . $rid);
    drupal_set_message(t('Registration page has been removed.'));
  }
  else {
    drupal_set_message(t('Registration page has not been removed. There are no pages for this role.'), 'error');
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function multiple_registration_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) {
  if (!isset($form['#instance'])) {
    return;
  }
  $instance = $form['#instance'];
  if ($instance['entity_type'] == 'user' && !$form['#field']['locked']) {
    $reg_pages = _multiple_registration_get_registration_pages();
    if ($reg_pages) {
      $roles = user_roles();
      $options[MULTIPLE_REGISTRATION_GENERAL_REGISTRATION_ID] = t('General registered users');
      foreach ($reg_pages as $rid => $page) {
        $options[$rid] = t('Users with !role role', array(
          '!role' => '<strong>' . $roles[$rid] . '</strong>',
        ));
      }
      $descr = t('Specify which of options are actual for this field. If nothing is selected, field is available for all variants.');
      if (isset($instance['settings']['user_additional_register_form'])) {
        $def_val = $instance['settings']['user_additional_register_form'];
      }
      else {
        $def_val = array();
      }
      $form['instance']['settings']['user_additional_register_form'] = array(
        '#type' => 'checkboxes',
        '#title' => t('This field is needed for:'),
        '#description' => $descr,
        '#default_value' => $def_val,
        // Show 2nd after required field.
        '#weight' => $form['instance']['settings']['user_register_form']['#weight'] + 0.1,
        '#options' => $options,
      );

      // Multiple registration 'required' options description and checks.
      if (empty($form['instance']['required']['#default_value'])) {
        $descr = t('<strong>Note: works only if "Required field" is unchecked!</strong>');
        if (isset($instance['settings']['user_additional_register_form_required'])) {
          $def_val = $instance['settings']['user_additional_register_form_required'];
        }
        else {
          $def_val = array();
        }

        // Multiple registration 'required' options.
        $form['instance']['settings']['user_additional_register_form_required'] = array(
          '#type' => 'checkboxes',
          '#title' => t('This field is required for:'),
          '#description' => $descr,
          '#default_value' => $def_val,
          '#weight' => $form['instance']['settings']['user_additional_register_form']['#weight'] + 0.1,
          '#options' => $options,
        );
      }
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function multiple_registration_form_user_register_form_alter(&$form, &$form_state, $form_id) {
  $rid = isset($form_state['reg_rid']) ? $form_state['reg_rid'] : NULL;
  if ($rid || strstr(current_path(), MULTIPLE_REGISTRATION_SIGNUP_PATH_PATTERN) && is_numeric(arg(2))) {
    $form_state['reg_rid'] = $rid ? $rid : arg(2);
    $form['#submit'][] = 'multiple_registration_user_register_form_submit';
    drupal_alter('multiple_registration_form', $form, $form_state, $form_state['reg_rid']);
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function multiple_registration_form_user_login_block_alter(&$form, &$form_state, $form_id) {
  if ($multiple_registration_pages = _multiple_registration_get_registration_pages()) {
    $user_roles = user_roles();
    foreach ($multiple_registration_pages as $rid => $url) {
      $items[] = l(t('Create new !role account', array(
        '!role' => $user_roles[$rid],
      )), $url);
    }
    $form['multiple_registration'] = array(
      '#markup' => theme('item_list', array(
        'items' => $items,
      )),
    );
  }
}

/**
 * Implements hook_field_group_pre_render().
 */
function multiple_registration_field_group_pre_render(&$element, $group, &$form) {
  $group_children = isset($group->children) ? $group->children : array();
  foreach ($group_children as $id => $field_name) {
    $instance = field_info_instance('user', $field_name, 'user');

    // Field is not accesible by user role.
    if (is_array($instance) && !multiple_registration_is_field_accessible($instance)) {
      unset($group_children[$id]);
    }
  }

  // If all fields from group are not accessible, hide this group.
  if (empty($group_children)) {
    field_group_hide_field_groups($form, array(
      $group->group_name,
    ));
  }
}

/**
 * Implements hook_module_implements_alter().
 *
 * We need to move to the bottom, because our form alter related
 * with other form alters, that should be implemented before our hook.
 */
function multiple_registration_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'form_alter' && isset($implementations['multiple_registration'])) {
    $group = $implementations['multiple_registration'];
    unset($implementations['multiple_registration']);
    $implementations['multiple_registration'] = $group;
  }
}

/**
 * Implements hook_field_widget_form_alter().
 */
function multiple_registration_field_widget_form_alter(&$element, &$form_state, $context) {
  $instance = isset($context['instance']) ? $context['instance'] : array();
  if (!empty($instance['settings']['user_additional_register_form'])) {

    // If nothing was selected.
    if (max($instance['settings']['user_additional_register_form']) === 0) {
      return;
    }
    $element['#access'] = multiple_registration_is_field_accessible($instance);
    if (!$element['#access']) {

      // Disable required property for the field if access is disabled.
      variable_set('is_current_field_accessible', FALSE);
      $element['value']['#required'] = FALSE;
    }

    // Mark field as required for special role regarding field configuration.
    if ($element['#access'] && isset($instance['settings']['user_additional_register_form_required'])) {
      $field_required_for = $instance['settings']['user_additional_register_form_required'];

      // Where arg(index) is a parsed current url index.
      if (arg(1) === 'signup') {
        if (in_array(arg(2), $field_required_for, TRUE)) {
          $element['value']['#required'] = TRUE;
          $element['#required'] = TRUE;
        }
      }
    }
  }
}

/**
 * Check is field accessible by user.
 *
 * @param array $instance
 *   Field instance data array.
 *
 * @return bool
 *   Return TRUE, if field accesible, FALSE - if is not accessible.
 */
function multiple_registration_is_field_accessible(array $instance) {

  // For registration form.
  if (!user_is_logged_in()) {
    return _multiple_registration_is_field_accessible_for_not_logged_in($instance);
  }
  else {
    return _multiple_registration_is_field_accessible_for_logged_in($instance);
  }
}

/**
 * Check is field accessible by logged in user.
 *
 * @param array $instance
 *   Field instance data array.
 *
 * @return bool
 *   Return TRUE, if field accesible, FALSE - if is not accessible.
 */
function _multiple_registration_is_field_accessible_for_logged_in(array $instance) {
  global $user;
  if (!isset($instance['settings']['user_additional_register_form'])) {
    return TRUE;
  }
  $user_roles = array_keys($user->roles);
  $field_roles = array_keys($instance['settings']['user_additional_register_form']);
  $extract_keys = array_intersect($user_roles, $field_roles);
  if ($extract_keys || user_access('administer users')) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Check is field accessible by non logged in user.
 *
 * @param array $instance
 *   Field instance data array.
 *
 * @return bool
 *   Return TRUE, if field accesible, FALSE - if is not accessible.
 */
function _multiple_registration_is_field_accessible_for_not_logged_in(array $instance) {
  if (!isset($instance['settings']['user_additional_register_form'])) {
    return TRUE;
  }

  // General registration.
  if (arg(1) == 'register') {
    $key = MULTIPLE_REGISTRATION_GENERAL_REGISTRATION_ID;
  }

  // Registration for role.
  if (strstr(current_path(), MULTIPLE_REGISTRATION_SIGNUP_PATH_PATTERN)) {
    $key = arg(2);
    if (!isset($instance['settings']['user_additional_register_form'][$key])) {
      $key = MULTIPLE_REGISTRATION_GENERAL_REGISTRATION_ID;
    }
  }
  if (isset($key) && $instance['settings']['user_additional_register_form'][$key] === 0) {
    return FALSE;
  }
  return TRUE;
}

/**
 * Disabling form element wrappers if field is not accessible for user role.
 *
 * @param string $op
 *    Current operation.
 * @param array $field
 *    Field attributes array.
 * @param string $entity_type
 *    Entity type.
 * @param object $entity
 *    Entity object.
 * @param object $account
 *    Account object.
 *
 * @return bool
 */
function multiple_registration_field_access($op, $field, $entity_type, $entity, $account) {
  if (variable_get('is_current_field_accessible') === FALSE) {
    variable_del('is_current_field_accessible');
    variable_set('is_current_field_accessible', TRUE);
    return FALSE;
  }
}

/**
 * Submit for user_register_form.
 */
function multiple_registration_user_register_form_submit($form, &$form_state) {
  if (isset($form['#user']->uid)) {
    $account = user_load($form['#user']->uid);
    $all_roles = user_roles();
    $rid = $form_state['reg_rid'];

    // Assign user role.
    $roles = $account->roles + array(
      $rid => $all_roles[$rid],
    );
    user_save($account, array(
      'roles' => $roles,
    ));
  }
}

/**
 * Implements hook_help().
 */
function multiple_registration_help($path, $arg) {
  switch ($path) {
    case 'admin/help#multiple_registration':
      $path = dirname(__FILE__) . '/README.txt';
      if (file_exists($path)) {
        $readme = file_get_contents($path);
      }
      if (!isset($readme)) {
        return NULL;
      }
      $output = '<pre>' . $readme . '</pre>';
      return $output;
  }
}

/**
 * Provides an ability for disabling default user registration form.
 *
 * @param $form
 * @param $form_state
 * @return mixed
 */
function multiple_registration_default_registration_form($form, $form_state) {
  $form['disable_default_registration_form'] = [
    '#type' => 'checkbox',
    '#title' => 'Disable default registration form?',
    '#default_value' => variable_get('disable_default_registration_form', 'FALSE'),
  ];
  $form = system_settings_form($form);
  return $form;
}

Functions

Namesort descending Description
multiple_registration_cc_flag Sets flag to clear cache.
multiple_registration_create_registration_form Form for creating new registration page.
multiple_registration_create_registration_form_submit Submit function for multiple_registration_create_registration_form.
multiple_registration_default_registration_form Provides an ability for disabling default user registration form.
multiple_registration_exit Implements hook_exit().
multiple_registration_field_access Disabling form element wrappers if field is not accessible for user role.
multiple_registration_field_group_pre_render Implements hook_field_group_pre_render().
multiple_registration_field_widget_form_alter Implements hook_field_widget_form_alter().
multiple_registration_form_field_ui_field_edit_form_alter Implements hook_form_FORM_ID_alter().
multiple_registration_form_user_login_block_alter Implements hook_form_FORM_ID_alter().
multiple_registration_form_user_register_form_alter Implements hook_form_FORM_ID_alter().
multiple_registration_help Implements hook_help().
multiple_registration_is_field_accessible Check is field accessible by user.
multiple_registration_menu Implements hook_menu().
multiple_registration_menu_alter Implements hook_menu_alter().
multiple_registration_module_implements_alter Implements hook_module_implements_alter().
multiple_registration_permission Implements hook_permission().
multiple_registration_remove_registration_form Form for removing registration page.
multiple_registration_remove_registration_form_submit Submit function for multiple_registration_remove_registration_form.
multiple_registration_settings_form Form for managing all created registration pages.
multiple_registration_theme_registry_alter Implements hook_theme_registry_alter().
multiple_registration_user_admin_roles Returns HTML for the role order and new role form.
multiple_registration_user_register_form_submit Submit for user_register_form.
_multiple_registration_get_registration_pages Get all role ids for whom registration forms was created.
_multiple_registration_is_field_accessible_for_logged_in Check is field accessible by logged in user.
_multiple_registration_is_field_accessible_for_not_logged_in Check is field accessible by non logged in user.
_multiple_registration_remove_page Removes registering page for role.
_multiple_registration_remove_page_alias Removes url aliases.

Constants

Namesort descending Description
MULTIPLE_REGISTRATION_GENERAL_REGISTRATION_ID
MULTIPLE_REGISTRATION_SIGNUP_PATH_PATTERN @file Add ability to create several registration pages.