You are here

og_massadd.module in Organic Groups Mass Add 7

Same filename and directory in other branches
  1. 6 og_massadd.module

The og_massadd module file

File

og_massadd.module
View source
<?php

/**
 * @file
 * The og_massadd module file
 */

/**
 * Implements of hook_permission().
 */
function og_massadd_permission() {
  return array(
    'mass add and create users' => array(
      'title' => t('OG mass add and create users'),
      'description' => t('OG mass add and create users'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function og_massadd_menu() {
  $items['admin/config/group/og_massadd'] = array(
    'title' => 'Og Mass Add',
    'description' => 'Configure og_massadd',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'og_massadd_admin_settings',
    ),
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer site configuration',
    ),
    'type' => MENU_NORMAL_ITEM,
    'file' => 'og_massadd.admin.inc',
  );
  $items['group/%/%/admin/people/mass-add-user'] = array(
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'og_massadd_massadd_form',
      1,
      2,
    ),
    'type' => MENU_LOCAL_TASK,
    'weight' => 5,
    'title' => 'Mass upload of user',
    'access callback' => 'og_ui_user_access_group',
    'access arguments' => array(
      'add user',
      1,
      2,
    ),
  );
  $items['group/%/%/admin/people/mass-add-user-filter'] = array(
    'page callback' => 'ogmass_add_user_filter',
    'page arguments' => array(
      1,
      2,
    ),
    'type' => MENU_LOCAL_TASK,
    'weight' => 4,
    'title' => 'Find and Add Members',
    'access callback' => 'og_ui_user_access_group',
    'access arguments' => array(
      'add user',
      1,
      2,
    ),
  );
  return $items;
}

/**
 * Callback to show the needed view to add users using VBO.
 */
function ogmass_add_user_filter($group_type, $group_id) {

  // check if user has access to view user profiles which is needed
  if (!user_access('access user profiles')) {
    drupal_set_message(t('You need to define permission "View user profiles" in
      order to add users to groups. Please configure the needed permission'), 'error');
    return '';
  }
  else {
    if (is_numeric($group_id)) {
      og_context($group_type, node_load($group_id));
      $view = views_get_view('og_massadd');
      $view
        ->set_arguments(array(
        $group_id,
      ));
      $view
        ->set_display('block_1');
      $view
        ->pre_execute();
      $view
        ->execute();
      $content = $view
        ->render();
      return $content;
    }
  }
}

/**
 * Implements hook_views_api().
 */
function og_massadd_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'og_massadd') . '/includes',
  );
}

/* implements of hook_og_ui_get_group_admin_alter(). */
function og_massadd_og_ui_get_group_admin_alter(&$data, $gid) {

  // Hijack the add people to use a custom implementation.

  //$data['add_people']['href'] = 'admin/people/mass-add-user-filter';
}

/**
 * Implements hook_og_ui_get_group_admin().
 */
function og_massadd_og_ui_get_group_admin($group_type, $gid) {
  $items = array();
  if (og_user_access($group_type, $gid, 'add user')) {
    $items['add_mass_people'] = array(
      'title' => t('Mass upload of user'),
      'description' => t('Mass add group members.'),
      'href' => 'admin/people/mass-add-user',
    );
    $items['find_add_mass_people'] = array(
      'title' => t('Find and add users'),
      'description' => t('Find and add group members.'),
      'href' => 'admin/people/mass-add-user-filter',
    );
  }
  return $items;
}

/**
 * Mass adding users form
 */
function og_massadd_massadd_form($form, &$form_state, $group_type, $group_id) {
  global $user;
  $form['group_type'] = array(
    '#type' => 'value',
    '#value' => $group_type,
  );
  $form['group_ids'] = array(
    '#type' => 'value',
    '#title' => t('Groups to add the user to'),
    '#value' => array(
      $group_id,
    ),
    '#required' => TRUE,
  );
  $form['massadd'] = array(
    '#type' => 'textarea',
    '#title' => t('List of users to add'),
    '#description' => t('A list of users to add. The contents can either be lines consiting of FIRSTNAME, LASTNAME, EMAIL or FIRSTNAME, LASTNAME, EMAIL, USERNAME or a list of email addresses (one on each line).'),
    '#rows' => 20,
    '#default_value' => '',
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Add users'),
  );
  return $form;
}

/**
 * Mass adding users validation
 */
function og_massadd_massadd_form_validate($form, &$form_state) {
  $gotfile = isset($_FILES['files']) && $_FILES['files']['name']['massadd_csv'] && is_uploaded_file($_FILES['files']['tmp_name']['massadd_csv']);
  if (!trim($form_state['values']['massadd']) && !$gotfile) {
    form_set_error('massadd', t("No users to add!"));
  }
  elseif (trim($form_state['values']['massadd']) && !_og_massadd_textareavalidate($form_state['values']['massadd'])) {
    form_set_error('massadd', t("Unknown format of userlist!"));
  }
}

/**
 * Validate text area contents
 */
function _og_massadd_textareavalidate($input) {
  $data = explode("\n", $input);
  foreach ($data as $i => $line) {
    if (trim($line)) {
      $line = array_map("trim", explode(",", $line));
      if (!(count($line) > 0 && count($line) < 5)) {

        // Check number of fields 1-5
        return FALSE;
      }
      if (count($line) == 5) {
        $email = $line[3];
      }
      else {
        $email = end($line);
      }
      if ((!valid_email_address($email) || empty($email)) && !user_load_by_name($email)) {
        return FALSE;
      }
    }
  }
  return TRUE;
}

/**
 * Mass adding users submit function
 */
function og_massadd_massadd_form_submit($form, &$form_state) {
  _og_massadd_fromstring($form_state['values']['massadd'], $form_state['values']['group_type'], $form_state['values']['group_ids']);
}

/**
 * Mass adding users from string input
 */
function _og_massadd_fromstring($input, $group_type, $group_ids) {

  // Fill our data array
  $data = explode("\n", $input);
  foreach ($data as $i => $line) {
    if (trim($line)) {
      $data[$i] = array_map("trim", explode(",", $line));
    }
    else {
      unset($data[$i]);
    }
  }
  $status = array(
    "new" => array(),
    "failed" => array(),
    "existing" => array(),
  );
  foreach ($data as $line) {
    $address = _og_massadd_adduser($line, $group_type, $group_ids);
    if ($address === FALSE) {
      $status['failed'][] = implode(",", $line);
    }
    elseif ($address == 0) {
      $status['existing'][] = implode(",", $line);
    }
    elseif ($address == 1) {
      $status['new'][] = implode(",", $line);
    }
  }
  if (count($status['new'])) {
    drupal_set_message(t("The following users were created and added to the group(s):") . "<br />" . implode("<br />", $status['new']));
  }
  if (count($status['existing'])) {
    drupal_set_message(t("The following users already had an account and were added to the group(s):") . "<br />" . implode("<br />", $status['existing']));
  }
  if (count($status['failed'])) {
    drupal_set_message(t("The following users could not be added:") . "<br />" . implode("<br />", $status['failed']), 'error');
  }
}

/**
 * Actually adding something
 * Returns FALSE if the user couldn't be created, 0 if the user existed and 1 if it was created.
 */
function _og_massadd_adduser($user, $group_type, $group_ids) {
  $newuser = array();
  if (count($user) == 1) {
    $firstname = "";
    $lastname = "";
    $mail = reset($user);
    $desiredname = "";
  }
  elseif (count($user) == 2) {
    $firstname = reset($user);
    $lastname = "";
    $mail = end($user);
    $desiredname = "";
  }
  elseif (count($user) == 3) {
    $firstname = reset($user);
    $lastname = next($user);
    $mail = end($user);
    $desiredname = "";
  }
  elseif (count($user) >= 4) {
    $firstname = reset($user);
    $lastname = next($user);
    $mail = next($user);
    $desiredname = end($user);
  }
  else {

    //dpm('Unable to count fields');
    return FALSE;
  }
  $didcreate = 0;

  // If it looks like a mail address, try to look up user
  if (valid_email_address($mail)) {
    $query = new EntityFieldQuery();
    $query
      ->entityCondition('entity_type', 'user')
      ->propertyCondition('mail', check_plain($mail));
    $result = $query
      ->execute();
    if (!empty($result)) {
      $uids = array_keys($result['user']);
      $account = user_load_multiple($uids);
      $account = array_shift($account);
    }
  }

  // If not, try to check for usernames
  if (!isset($account) && drupal_strlen($mail)) {
    $query = new EntityFieldQuery();
    $query
      ->entityCondition('entity_type', 'user')
      ->propertyCondition('name', check_plain($mail));
    $result = $query
      ->execute();
    if (!empty($result)) {
      $uids = array_keys($result['user']);
      $account = user_load_multiple($uids);
      $account = array_shift($account);
    }
  }

  // Create user if necessary
  if (!isset($account) && !valid_email_address($mail)) {

    //dpm($mail, 'Not valid email address');
    return FALSE;
  }
  elseif (!isset($account) && valid_email_address($mail)) {
    if (!user_access('mass add and create users') || !variable_get("og_massadd_createunknowns", FALSE)) {

      //dpm('Not allowed to create unknowns');
      return FALSE;
    }
    $newuser['mail'] = $mail;
    $newuser['pass'] = user_password();
    $newuser['init'] = $newuser['mail'];
    $newuser['status'] = 1;

    // 20 attempts should be enough for anybody (tm)
    for ($attempt = 0; $attempt <= 20; $attempt++) {
      $newuser['name'] = _og_massadd_createusername($mail, $firstname, $lastname, $desiredname, $attempt);
      if ($newuser['name'] !== FALSE && !db_query("SELECT count(*) FROM {users} WHERE name = :name", array(
        ':name' => check_plain($newuser['name']),
      ))
        ->fetchField()) {
        $account = user_save(NULL, $newuser);
        if ($account !== FALSE) {
          $account->password = $newuser['pass'];
          _user_mail_notify('register_no_approval_required', $account);
          $didcreate = 1;
          break;

          // Got user, end tries
        }
      }
    }
    if (!$account) {

      // Exhausted attempts, give up

      //dpm('Unable to find available username');
      return FALSE;
    }
  }
  if (variable_get('og_massadd_createunknowns', '')) {
    $fname = variable_get('og_massadd_profilefname', '');
    $lname = variable_get('og_massadd_profilelname', '');
    if (drupal_strlen($fname) && field_info_field($fname)) {
      $account->{$fname}['und'][0]['value'] = $firstname;
    }
    if (drupal_strlen($lname) && field_info_field($lname)) {
      $account->{$lname}['und'][0]['value'] = $lastname;
    }
    user_save($account);

    // Actually, we don't care if this fails for now. We need better field-handling first.
  }

  // Add user to groups
  foreach ($group_ids as $gid) {
    if ($gid) {
      $field_names = og_get_group_audience_fields();
      $field_name = !empty($form_state['values']['field_name']) ? $form_state['values']['field_name'] : key($field_names);

      /* user already belongs to the group */
      if (og_get_membership($group_type, $gid, 'user', $account->uid)) {
        return FALSE;
      }
      $ret = og_membership_create($group_type, $gid, 'user', $account->uid, $field_name);
      $ret
        ->save();

      /*
           $groupnode = node_load($gid);
           $variables = array(
             '@title' => $groupnode->title,
             '!group_url' => url("node/$groupnode->nid", array('absolute' => TRUE))
           );
           drupal_mail('og', 'approve_user', $account->mail, user_preferred_language($account), $variables);
      */
    }
  }
  return $didcreate;
}

/**
 * Generate a preferred username
 */
function _og_massadd_createusername($email, $firstname = '', $lastname = '', $suggestion = '', $attempt = 0) {

  /*
  The following combinations are tried in order:

  1: If one is provided, the suggested username
  2. The first part of the email address (everything before the @)
  3. If both firstname and lastname is provided, "F.L".
    F is x number of letters from firstname, where x starts at 1 and goes up to the full length of firstname.
    L is lastname.
  4. If firstname is provided without lastname, firstname only.
  5. If lastname is provided without firstname, lastname only.
  6. If both firstname and lastname is provided, try adding numbers 1 and up to a name formatted as F.Lastname where F is the first letter of firstname.
  7. Last (only performed if the previous combination didn't) add numbers 1 and up to the first part of the email address.
  */
  $usernames = array();
  $numbered = array();

  // First, create the verbatim names to try
  // #1 pri: suggested username
  if (!empty($suggestion)) {
    $usernames[] = $suggestion;
  }

  // #2 pri: first part of email address (always present)
  preg_match('/^(.+)(?:@)/', $email, $matches);
  if (!empty($matches[1])) {
    $usernames[] = $matches[1];
  }
  else {
    return FALSE;

    // We DO need a valid mail address
  }

  // #3 pri: username on the form of [x number of letters from first name, starting from 1 and up].[lastname]
  if (!empty($firstname) && !empty($lastname)) {
    for ($i = 1; $i < drupal_strlen($firstname); $i++) {
      $username = '';
      if (!empty($firstname)) {

        // Add firstname if present
        $username .= drupal_substr($firstname, 0, $i);
      }
      if (!empty($firstname) && !empty($lastname)) {

        // Add divider between first and last name
        $username .= '.';
      }
      if (!empty($lastname)) {

        // Add lastname
        $username .= $lastname;
      }
      $usernames[] = $username;
    }
  }

  // #4 pri: if no lastname, use firstname only
  if (!empty($firstname) && empty($lastname)) {
    $usernames[] = $firstname;
  }

  // #5 pri: if no firstname, use lastname only
  if (empty($firstname) && !empty($lastname)) {
    $usernames[] = $lastname;
  }

  // Create names to add numbers to as last resort. Different priorities than the verbatim names
  // #1 pri: [first letter of first name].[lastname]
  if (!empty($firstname) && !empty($lastname)) {
    $numbered[] = drupal_substr($firstname, 0, 1) . '.' . $lastname;
  }

  // #2 pri: first part of email address (always present)
  preg_match('/^(.+)(?:@)/', $email, $matches);
  if (!empty($matches[1])) {
    $numbered[] = $matches[1];
  }

  // If our attempt exists in the verbatim table, return it
  if (isset($usernames[$attempt])) {
    return $usernames[$attempt];
  }

  // Generate a numbered attempt using the first entry in the numbered table.
  $attempt = $attempt - count($usernames);
  return reset($numbered) . ($attempt + 1);
}

Functions

Namesort descending Description
ogmass_add_user_filter Callback to show the needed view to add users using VBO.
og_massadd_massadd_form Mass adding users form
og_massadd_massadd_form_submit Mass adding users submit function
og_massadd_massadd_form_validate Mass adding users validation
og_massadd_menu Implements hook_menu().
og_massadd_og_ui_get_group_admin Implements hook_og_ui_get_group_admin().
og_massadd_og_ui_get_group_admin_alter
og_massadd_permission Implements of hook_permission().
og_massadd_views_api Implements hook_views_api().
_og_massadd_adduser Actually adding something Returns FALSE if the user couldn't be created, 0 if the user existed and 1 if it was created.
_og_massadd_createusername Generate a preferred username
_og_massadd_fromstring Mass adding users from string input
_og_massadd_textareavalidate Validate text area contents