You are here

subuser.pages.inc in Subuser 6

Allows users of a particular role to create sub user account in another role.

Copyright 2008-2009 by Jimmy Berry ("boombatower", http://drupal.org/user/214218)

File

subuser.pages.inc
View source
<?php

/**
 * @file
 * Allows users of a particular role to create sub user account in another role.
 *
 * Copyright 2008-2009 by Jimmy Berry ("boombatower", http://drupal.org/user/214218)
 */

/**
 * Sub user settings form.
 */
function subuser_settings_form(&$form_state) {
  $form = array();

  // Get all non-default roles.
  $roles = user_roles(TRUE);
  unset($roles[DRUPAL_ANONYMOUS_RID]);
  unset($roles[DRUPAL_AUTHENTICATED_RID]);
  $form['display'] = array(
    '#type' => 'fieldset',
    '#title' => t('Display'),
    '#description' => t('Configure the wording used for creating a subuser.'),
  );
  $form['display']['subuser_parent'] = array(
    '#type' => 'textfield',
    '#title' => t('Parent'),
    '#description' => t('Name for parent user.'),
    '#default_value' => SUBUSER_PARENT,
  );
  $form['display']['subuser_list'] = array(
    '#type' => 'textfield',
    '#title' => t('List'),
    '#description' => t('Displayed above a users list of subusers.'),
    '#default_value' => SUBUSER_LIST,
  );
  $form['display']['subuser_create'] = array(
    '#type' => 'textfield',
    '#title' => t('Create'),
    '#description' => t('The text used for the link and page title when creating a subuser.'),
    '#default_value' => SUBUSER_CREATE,
  );
  $form['display']['subuser_administer'] = array(
    '#type' => 'textfield',
    '#title' => t('Administer'),
    '#description' => t('The text used for the link and page title when administering subusers.'),
    '#default_value' => SUBUSER_ADMINISTER,
  );
  if ($roles) {
    $form['roles'] = array(
      '#type' => 'fieldset',
      '#title' => t('Roles'),
      '#description' => t('Choose the roles you would like for sub users to automatically have when created.'),
    );
    $form['roles']['subuser_roles'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Available roles'),
      '#options' => $roles,
      '#default_value' => variable_get('subuser_roles', array()),
    );
  }
  else {
    drupal_set_message(t('No available roles to select. Please <a href="@admin-role">create a role</a>.', array(
      '@admin-role' => url("admin/user/roles"),
    )), 'error');
  }
  $form['advanced'] = array(
    '#type' => 'fieldset',
    '#title' => t('Advanced settings'),
  );
  $form['advanced']['subuser_limit'] = array(
    '#type' => 'textfield',
    '#title' => t('Subuser account limit'),
    '#default_value' => variable_get('subuser_limit', 0),
    '#description' => t("Specify a maximum number of subuser accounts per user. Leave as '0' for no limit."),
    '#size' => 3,
  );
  $form['advanced']['subuser_children_block'] = array(
    '#type' => 'select',
    '#title' => t('When parents are blocked are children blocked?'),
    '#description' => t("If 'yes' is selected when a parent account is blocked the associated children will be blocked as well"),
    '#options' => array(
      0 => 'No',
      1 => 'Yes',
    ),
    '#default_value' => variable_get('subuser_children_block', 1),
  );
  $form['advanced']['subuser_children_unblock'] = array(
    '#type' => 'select',
    '#title' => t('When parents are unblocked are children unblocked?'),
    '#description' => t("If 'yes' is selected when a parent account is unblocked the associated children will be unblocked as well."),
    '#options' => array(
      0 => 'No',
      1 => 'Yes',
    ),
    '#default_value' => variable_get('subuser_children_unblock', 1),
  );
  $form['advanced']['subuser_children_roles'] = array(
    '#type' => 'select',
    '#title' => t('When parents roles change should the child account change to match?'),
    '#description' => t("If 'yes' is selected and the roles of a parent account change the child accounts will have the same role additions or subtractions."),
    '#options' => array(
      0 => 'No',
      1 => 'Yes',
    ),
    '#default_value' => variable_get('subuser_children_roles', 1),
  );
  $form['advanced']['subuser_cascade_exempt_rid'] = array(
    '#type' => 'select',
    '#title' => t('Should we exempt any role from the cascading behavior?'),
    '#description' => t('A role set here will not cascade down to subusers. This allows one role to be given add subuser permission, without that role accidentally propagating down to subusers.'),
    '#options' => user_roles(),
    '#default_value' => variable_get('subuser_cascade_exempt_rid', NULL),
  );
  $form['advanced']['subuser_copy_parent_roles'] = array(
    '#type' => 'select',
    '#title' => t('On subuser creation, the subuser should get all the roles of a parent (except for the role prevented from cascading behaviour)'),
    '#description' => t("If 'yes' is selected, the subuser should get all the roles of a parent (except the role exempt from cascading behaviour). Also the roles marked above in 'Choose the roles you would like for subusers to automatically have when created will be given to the subuser in addition to parent roles."),
    '#options' => array(
      0 => 'No',
      1 => 'Yes',
    ),
    '#default_value' => variable_get('subuser_copy_parent_roles', 0),
  );
  $form['advanced']['subuser_orphaned_children'] = array(
    '#type' => 'select',
    '#title' => t('How are orphaned child accounts handled?'),
    '#default_value' => variable_get('subuser_orphaned_children', 0),
    '#description' => t('Choose how to handle subuser accounts when the parent account is deleted.'),
    '#options' => array(
      0 => t('Do Nothing'),
      1 => t('Block the Subusers'),
      // TODO It would be nice to allow a role shift here instead too...
      2 => t('Delete the Subusers'),
    ),
  );

  // Should we show the default administer links on the user page?
  $form['advanced']['subuser_show_admin'] = array(
    '#type' => 'select',
    '#title' => t('Show administer link on user form'),
    '#options' => array(
      0 => t('No'),
      1 => t('Yes'),
    ),
    '#default_value' => variable_get('subuser_show_admin', 1),
  );

  // Should parent be cc'd when subusers are sent mail?
  $form['advanced']['subuser_cc_parent'] = array(
    '#type' => 'select',
    '#title' => t('CC parent when subusers are sent mail'),
    '#options' => array(
      0 => t('No'),
      1 => t('Yes'),
    ),
    '#default_value' => variable_get('subuser_cc_parent', 0),
  );

  // Ensure that menu rebuild takes place after variables have been saved.
  $form = system_settings_form($form);
  $form['#validate'][] = 'subuser_settings_form_validate';
  $form['#submit'][] = 'subuser_settings_form_submit';
  return $form;
}

/**
 * Validate the subuser settings form.
 */
function subuser_settings_form_validate(&$form, &$form_state) {

  // Make sure the subuser_limit is a number.
  if (!is_numeric($form_state['values']['subuser_limit'])) {
    form_set_error('subuser_limit', t('The !limit must be specified as an integer.', array(
      '!limit' => $form['advanced']['subuser_limit']['#title'],
    )));
  }
}

/**
 * Rebuild menu to ensure that display settings take effect.
 */
function subuser_settings_form_submit($form, &$form_state) {
  menu_rebuild();
}

/**
 * Create subuser form.
 *
 * @param object $user User object.
 */
function subuser_create_form(&$form_state, $user) {
  $subuser_limit = subuser_get_subuser_limit($user->uid);
  if (!user_access('bypass subuser limit') && $subuser_limit && count(subuser_get_subusers($user->uid)) >= $subuser_limit) {
    drupal_set_message(t('You have already reached your limit of !limit subusers.', array(
      '!limit' => $subuser_limit,
    )), 'warning');
    drupal_goto(referer_uri());
  }
  $form = array();
  $form['parent_user'] = array(
    '#type' => 'value',
    '#value' => $user->uid,
  );
  $form['origin'] = array(
    '#type' => 'value',
    '#value' => 'subuser',
  );
  $form['destination'] = array(
    '#type' => 'hidden',
    '#value' => 'user/' . $user->uid,
  );
  $form['account'] = array(
    '#type' => 'fieldset',
    '#title' => t('Account information'),
    '#weight' => -10,
  );
  $form['account']['status'] = array(
    '#type' => 'value',
    '#value' => TRUE,
  );
  $form['account']['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Username'),
    '#default_value' => NULL,
    '#maxlength' => 60,
    '#description' => 'Spaces are allowed; punctuation is not allowed except for periods, hyphens, and underscores.',
    '#required' => TRUE,
  );
  $form['account']['mail'] = array(
    '#type' => 'textfield',
    '#title' => t('E-mail address'),
    '#default_value' => NULL,
    '#maxlength' => 64,
    '#description' => 'A valid e-mail address. All e-mails from the system will be sent to this address. The e-mail address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by e-mail.',
    '#required' => TRUE,
  );
  $form['account']['pass'] = array(
    '#type' => 'password_confirm',
    '#description' => 'Provide a password for the new account in both fields.',
    '#required' => TRUE,
    '#size' => 25,
  );
  $form['account']['notify'] = array(
    '#type' => 'checkbox',
    '#title' => t('Notify user of new account'),
  );
  $form['roles'] = array(
    '#type' => 'value',
    '#value' => variable_get('subuser_roles', array()),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Create new account'),
    '#weight' => 30,
  );
  $form['#validate'] = array(
    'user_register_validate',
  );
  return $form;
}

/**
 * Modified copy of user_register_submit().
 *
 * Just changed permission line, and removed uid == 1 case, which should never
 * occur.
 */
function subuser_create_form_submit($form, &$form_state) {
  global $base_url;
  $admin = user_access('create subuser');
  $mail = $form_state['values']['mail'];
  $name = $form_state['values']['name'];
  if (!variable_get('user_email_verification', TRUE) || $admin) {
    $pass = $form_state['values']['pass'];
  }
  else {
    $pass = user_password();
  }
  $notify = isset($form_state['values']['notify']) ? $form_state['values']['notify'] : NULL;
  $from = variable_get('site_mail', ini_get('sendmail_from'));
  if (isset($form_state['values']['roles'])) {

    // Remove unset roles.
    $roles = array_filter($form_state['values']['roles']);
  }
  else {
    $roles = array();
  }
  $parent_user_id = $form_state['values']['parent_user'];
  $parent_user = user_load($parent_user_id);
  $can_copy_parent_roles = variable_get('subuser_copy_parent_roles', 0);
  if ($can_copy_parent_roles) {
    $exempt_role = variable_get('subuser_cascade_exempt_rid', NULL);
    $parent_roles = $parent_user->roles;

    // Remove exempt role if it exists.
    if (!empty($exempt_role) && array_key_exists($exempt_role, $parent_roles)) {
      unset($parent_roles[$exempt_role]);
    }
    $roles += $parent_roles;
  }

  // Provide a hook to allow other modules a chance to change the roles as they see fit.
  foreach (module_implements('subuser_create_alter_roles') as $module) {
    $func = $module . '_subuser_create_alter_roles';
    $func($roles, $parent_user);
  }
  if (!$admin && array_intersect(array_keys($form_state['values']), array(
    'uid',
    'roles',
    'init',
    'session',
    'status',
  ))) {
    watchdog('security', 'Detected malicious attempt to alter protected user fields.', array(), WATCHDOG_WARNING);
    $form_state['redirect'] = 'user/register';
    return;
  }

  // The unset below is needed to prevent these form values from being saved as
  // user data.
  unset($form_state['values']['form_token'], $form_state['values']['submit'], $form_state['values']['op'], $form_state['values']['notify'], $form_state['values']['form_id'], $form_state['values']['affiliates'], $form_state['values']['destination']);
  $merge_data = array(
    'pass' => $pass,
    'init' => $mail,
    'roles' => $roles,
  );
  if (!$admin) {

    // Set the user's status because it was not displayed in the form.
    $merge_data['status'] = variable_get('user_register', 1) == 1;
  }
  $account = user_save('', array_merge($form_state['values'], $merge_data));

  // Terminate if an error occured during user_save().
  if (!$account) {
    drupal_set_message(t("Error saving user account."), 'error');
    $form_state['redirect'] = '';
    return;
  }
  $form_state['user'] = $account;
  watchdog('user', 'New user: %name (%email).', array(
    '%name' => $name,
    '%email' => $mail,
  ), WATCHDOG_NOTICE, l(t('edit'), 'user/' . $account->uid . '/edit'));

  // Add plain text password into user account to generate mail tokens.
  $account->password = $pass;
  if ($admin && !$notify) {
    drupal_set_message(t('Created a new user account for <a href="@url">%name</a>. No e-mail has been sent.', array(
      '@url' => url("user/{$account->uid}"),
      '%name' => $account->name,
    )));
  }
  elseif (!variable_get('user_email_verification', TRUE) && $account->status && !$admin) {

    // No e-mail verification is required, create new user account, and login
    // user immediately.
    _user_mail_notify('register_no_approval_required', $account);
    if (user_authenticate(array_merge($form_state['values'], $merge_data))) {
      drupal_set_message(t('Registration successful. You are now logged in.'));
    }
    $form_state['redirect'] = '';
    return;
  }
  elseif ($account->status || $notify) {

    // Create new user account, no administrator approval required.
    $op = $notify ? 'register_admin_created' : 'register_no_approval_required';
    _user_mail_notify($op, $account);
    if ($notify) {
      drupal_set_message(t('Password and further instructions have been e-mailed to the new user <a href="@url">%name</a>.', array(
        '@url' => url("user/{$account->uid}"),
        '%name' => $account->name,
      )));
    }
    else {
      drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.'));
      $form_state['redirect'] = '';
      return;
    }
  }
  else {

    // Create new user account, administrator approval required.
    _user_mail_notify('register_pending_approval', $account);
    drupal_set_message(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.<br />In the meantime, a welcome message with further instructions has been sent to your e-mail address.'));
    $form_state['redirect'] = '';
    return;
  }
}

Functions

Namesort descending Description
subuser_create_form Create subuser form.
subuser_create_form_submit Modified copy of user_register_submit().
subuser_settings_form Sub user settings form.
subuser_settings_form_submit Rebuild menu to ensure that display settings take effect.
subuser_settings_form_validate Validate the subuser settings form.