Index: LICENSE.txt
===================================================================
diff -u -p -N LICENSE.txt
--- /dev/null
+++ LICENSE.txt	17 Oct 2008 17:59:09 -0000
@@ -0,0 +1,274 @@
+GNU GENERAL PUBLIC LICENSE
+
+              Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,
+Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute
+verbatim copies of this license document, but changing it is not allowed.
+
+                  Preamble
+
+The licenses for most software are designed to take away your freedom to
+share and change it. By contrast, the GNU General Public License is
+intended to guarantee your freedom to share and change free software--to
+make sure the software is free for all its users. This General Public License
+applies to most of the Free Software Foundation's software and to any other
+program whose authors commit to using it. (Some other Free Software
+Foundation software is covered by the GNU Library General Public License
+instead.) You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the
+freedom to distribute copies of free software (and charge for this service if
+you wish), that you receive source code or can get it if you want it, that you
+can change the software or use pieces of it in new free programs; and that
+you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to
+deny you these rights or to ask you to surrender the rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for
+a fee, you must give the recipients all the rights that you have. You must make
+sure that they, too, receive or can get the source code. And you must show
+them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software. If the
+software is modified by someone else and passed on, we want its recipients
+to know that what they have is not the original, so that any problems
+introduced by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that redistributors of a free program will individually
+obtain patent licenses, in effect making the program proprietary. To prevent
+this, we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+           GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
+               MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms
+of this General Public License. The "Program", below, refers to any such
+program or work, and a "work based on the Program" means either the
+Program or any derivative work under copyright law: that is to say, a work
+containing the Program or a portion of it, either verbatim or with
+modifications and/or translated into another language. (Hereinafter, translation
+is included without limitation in the term "modification".) Each licensee is
+addressed as "you".
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running the Program is
+not restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made
+by running the Program). Whether that is true depends on what the Program
+does.
+
+1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this License
+and to the absence of any warranty; and give any other recipients of the
+Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it,
+thus forming a work based on the Program, and copy and distribute such
+modifications or work under the terms of Section 1 above, provided that you
+also meet all of these conditions:
+
+a) You must cause the modified files to carry prominent notices stating that
+you changed the files and the date of any change.
+
+b) You must cause any work that you distribute or publish, that in whole or in
+part contains or is derived from the Program or any part thereof, to be
+licensed as a whole at no charge to all third parties under the terms of this
+License.
+
+c) If the modified program normally reads commands interactively when run,
+you must cause it, when started running for such interactive use in the most
+ordinary way, to print or display an announcement including an appropriate
+copyright notice and a notice that there is no warranty (or else, saying that
+you provide a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this License.
+(Exception: if the Program itself is interactive but does not normally print such
+an announcement, your work based on the Program is not required to print
+an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Program, and can be
+reasonably considered independent and separate works in themselves, then
+this License, and its terms, do not apply to those sections when you distribute
+them as separate works. But when you distribute the same sections as part
+of a whole which is a work based on the Program, the distribution of the
+whole must be on the terms of this License, whose permissions for other
+licensees extend to the entire whole, and thus to each and every part
+regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your rights to
+work written entirely by you; rather, the intent is to exercise the right to
+control the distribution of derivative or collective works based on the
+Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of a
+storage or distribution medium does not bring the other work under the scope
+of this License.
+
+3. You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of Sections 1
+and 2 above provided that you also do one of the following:
+
+a) Accompany it with the complete corresponding machine-readable source
+code, which must be distributed under the terms of Sections 1 and 2 above
+on a medium customarily used for software interchange; or,
+
+b) Accompany it with a written offer, valid for at least three years, to give
+any third party, for a charge no more than your cost of physically performing
+source distribution, a complete machine-readable copy of the corresponding
+source code, to be distributed under the terms of Sections 1 and 2 above on
+a medium customarily used for software interchange; or,
+
+c) Accompany it with the information you received as to the offer to distribute
+corresponding source code. (This alternative is allowed only for
+noncommercial distribution and only if you received the program in object
+code or executable form with such an offer, in accord with Subsection b
+above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source code
+means all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation and
+installation of the executable. However, as a special exception, the source
+code distributed need not include anything that is normally distributed (in
+either source or binary form) with the major components (compiler, kernel,
+and so on) of the operating system on which the executable runs, unless that
+component itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to
+copy from a designated place, then offering equivalent access to copy the
+source code from the same place counts as distribution of the source code,
+even though third parties are not compelled to copy the source along with the
+object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License. Any attempt otherwise to copy,
+modify, sublicense or distribute the Program is void, and will automatically
+terminate your rights under this License. However, parties who have received
+copies, or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it.
+However, nothing else grants you permission to modify or distribute the
+Program or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the
+Program (or any work based on the Program), you indicate your acceptance
+of this License to do so, and all its terms and conditions for copying,
+distributing or modifying the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these terms and
+conditions. You may not impose any further restrictions on the recipients'
+exercise of the rights granted herein. You are not responsible for enforcing
+compliance by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues), conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from the
+conditions of this License. If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Program at all.
+For example, if a patent license would not permit royalty-free redistribution
+of the Program by all those who receive copies directly or indirectly through
+you, then the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or
+other property right claims or to contest validity of any such claims; this
+section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices. Many
+people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose
+that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original copyright
+holder who places the Program under this License may add an explicit
+geographical distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus excluded. In such
+case, this License incorporates the limitation as if written in the body of this
+License.
+
+9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will be
+similar in spirit to the present version, but may differ in detail to address new
+problems or concerns.
+
+Each version is given a distinguishing version number. If the Program specifies
+a version number of this License which applies to it and "any later version",
+you have the option of following the terms and conditions either of that
+version or of any later version published by the Free Software Foundation. If
+the Program does not specify a version number of this License, you may
+choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission. For software which is copyrighted by the Free Software
+Foundation, write to the Free Software Foundation; we sometimes make
+exceptions for this. Our decision will be guided by the two goals of
+preserving the free status of all derivatives of our free software and of
+promoting the sharing and reuse of software generally.
+
+               NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE,
+THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT
+PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
+WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
+AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR
+ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
+SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OR INABILITY TO USE THE
+PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
+OR DATA BEING RENDERED INACCURATE OR LOSSES
+SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
+PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN
+IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.
+
+          END OF TERMS AND CONDITIONS
Index: supported/content.inc
===================================================================
diff -u -p -N supported/nodeprofile.inc
--- /dev/null
+++ supported/nodeprofile.inc	17 Oct 2008 17:59:09 -0000
@@ -0,0 +1,107 @@
+<?php
+// $Id: $
+
+/**
+ * @file
+ * Import node_import and cck module properties.
+ */
+
+// Functionality depends on node_import and CCK.
+if (module_exists('node_import') && module_exists('content')) {
+
+  // Load the required API files.
+  include_once(drupal_get_path('module', 'node_import') .'/node_import.api.inc');
+  node_import_load_supported();
+
+  /**
+   * Implementation of hook_user_import_form_field_match().
+   */
+  function nodeprofile_user_import_form_field_match() {
+    $options = array();
+    $options['nodeprofile'] = array();
+
+    $nodeprofile_types = (array) nodeprofile_get_types('types');
+
+    foreach (nodeprofile_get_types() as $type => $data) {
+      $fields = node_import_fields($type);
+      // Give fields a more descriptive title.
+      foreach (array_keys($fields) as $key) {
+        $fields[$key] = str_replace(t('Node: '), '', $fields[$key]);
+        $fields[$key] = t('Node profile: !key', array('!key' => $fields[$key]));
+      }
+      $options['nodeprofile'] = array_merge($options['nodeprofile'], $fields);
+    }
+
+    return $options;
+  }
+
+  /**
+   * Implementation of hook_user_import_data().
+   */
+  function nodeprofile_user_import_data($settings, $column_settings, $module, $field_id, $data, $column_id) {
+
+    if ($module != 'nodeprofile') return;
+
+    return trim($data[$column_id]);
+  }
+
+  /**
+   * Implementation of hook_user_import_after_save().
+   */
+  function nodeprofile_user_import_after_save($settings, $account, $password, $fields) {
+    if (!is_array($fields['nodeprofile'])) return;
+
+    $nodeprofile_types = (array) nodeprofile_get_types();
+
+    foreach (array_keys($nodeprofile_types) as $type) {
+      $errors = array();
+      $node = new stdClass();
+      $node->type = $type;
+      $node->status = 1;
+      // Assign the mapped fields to the $node.
+      foreach ($fields['nodeprofile'] as $column_id => $column_data) {
+        if (!empty($column_data)) {
+          $node->$column_id = $column_data[0];
+        }
+      }
+
+      // Call the node import preparation.
+      foreach (module_list() as $module_name) {
+        $function = $module_name .'_node_import_prepare';
+        if (function_exists($function)) {
+          $errors = array_merge((array)$errors, (array)$function($node, $preview > 0));
+        }
+      }
+
+      if (empty($errors)) {
+        $node->uid = $account->uid;
+        $node->name = $account->name;
+
+        // Assign a default title if one has not already been mapped.
+        if (!isset($node->title) || empty($node->title)) {
+          $node->title = $node->name;
+        }
+
+        $node = node_submit($node);
+
+        // Look for an existing node. This works because profile node types
+        // can only have one node per user.
+        // change to:
+        // if ($old_node = node_load($type, $account->uid)) {
+        // using node_load() to temporarely avoid upgrading nodeprofile
+        if ($old_node = node_load(array('type' => $node->type, 'uid' => $account->uid))) {
+          // By explicitly setting a nid value, we force an update.
+          $node->nid = $old_node->nid;
+        }
+
+        node_save($node);
+        // option to delete user if nodeprofile error
+      }
+      else {
+        // report errors
+      }
+    }
+
+    return;
+  }
+}
\ No newline at end of file
Index: supported/og.inc
===================================================================
diff -u -p -N supported/og.inc
--- /dev/null
+++ supported/og.inc	17 Oct 2008 17:59:09 -0000
@@ -0,0 +1,141 @@
+<?php
+// $Id: $
+
+/**
+ * @file
+ * Import organic groups module properties.
+ */
+
+/**
+ * Implementation of hook_user_import_form_fieldsets().
+ */
+function og_user_import_form_fieldset($import, $collapsed) {
+
+  $groups = user_import_get_groups();
+
+  $groups_description = empty($groups) ? t('No Groups have been defined.') : t('Select which group(s) imported users should be assigned.');
+
+  $form['group_assign'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Group Assign'),
+    '#description' => $groups_description,
+    '#collapsible' => TRUE,
+    '#collapsed' => $collapsed,
+  );
+
+  if (!empty($groups)) {
+    $form['group_assign']['groups'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Groups'),
+      '#options' => $groups,
+      '#default_value' => $import['options']['groups'],
+    );
+
+    $form['group_assign']['existing'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Existing Users'),
+      '#description' => t('Add to selected groups users who already have an account. Optionaly send them an email.'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+    );
+
+    $form['group_assign']['existing']['existing_og_subscribe'] = array(
+      '#type' => 'radios',
+      '#title' => t('Subscribe'),
+      '#default_value' => $import['options']['existing_og_subscribe'],
+      '#options' => array(t('No'), t('Yes')),
+    );
+
+    $form['group_assign']['existing']['existing_og_subject'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Message Subject'),
+      '#default_value' => $import['options']['existing_og_subject'],
+      '#description' => t('Customize the subject of the email sent to existing users being added to groups.') .' '. t('Available variables are:') .' !username, !site, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url'. $profile_string .'.',
+    );
+
+    $form['group_assign']['existing']['existing_og_markup'] = array(
+      '#type' => 'radios',
+      '#title' => t('Email Format'),
+      '#default_value' => empty($import['options']['existing_og_markup']) ? 0 : $import['options']['existing_og_markup'],
+      '#options' => array(t('Plain Text'), t('HTML')),
+    );
+
+    $form['group_assign']['existing']['existing_og_message'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Email Body'),
+      '#default_value' => $import['options']['existing_og_message'],
+      '#description' => t('Message to send existing users being added to groups. Users who are already in a group will not be sent a message.') .' '. t('Available variables are:') .' !username, !site, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url'. $profile_string .'.',
+    );
+
+    $form['group_assign']['existing']['existing_og_css'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Email CSS'),
+      '#default_value' => $import['options']['existing_og_css'],
+      '#description' => t('Use if sending HTML formated email.'),
+    );
+
+  }
+
+  return $form;
+}
+
+
+/**
+ * Implementation of hook_user_import_pre_save().
+ */
+function og_user_import_pre_save($settings, $account, $password, $fields, $errors) {
+
+  // user already exists - add to group?
+  if (in_array('duplicate email', $errors)) og_user_import_group_add($settings, $email, $fields);
+
+  return;
+}
+
+/**
+ * Implementation of hook_user_import_after_save().
+ */
+function og_user_import_after_save($settings, $account, $password, $fields) {
+
+  $groups_selected = $settings['options']['groups'];
+  $uid = $account->uid;
+
+  $organic_groups = user_import_get_groups();
+  if (empty($organic_groups)) return;
+
+  $og_args = array('is_active' => 1, 'is_admin' => 0, 'mail_type' => 0, 'created' => time());
+
+  while (list($gid, $title) = each($organic_groups)) {
+
+      if (!empty($groups_selected[$gid])) og_save_subscription($gid, $uid, $og_args);
+  }
+
+  return;
+}
+
+
+// add user to groups if already a member
+function og_user_import_group_add($settings, $email, $fields) {
+
+  if ($settings['setting'] != 'import') return;
+
+  $account = user_load(array('mail' => $email));
+  if (!empty($settings['options']['existing_og_message'])) $profile = user_import_profile_load($account);
+
+  $groups_subscribed = og_get_subscriptions($account->uid);
+  $og_args = array('is_active' => 1, 'is_admin' => 0, 'mail_type' => 0, 'created' => time());
+
+  foreach ($settings['groups'] as $group) {
+
+    // is user member of group?
+    if (!empty($group) && empty($groups_subscribed[$group])) {
+
+      // subscribe to group
+      og_save_subscription($group, $account->uid, $og_args);
+
+      if (!empty($settings['options']['existing_og_message'])) _user_import_send_email($account, $password, $profile, $settings['options']['existing_og_subject'], $settings['options']['existing_og_message'], $settings['options']['existing_og_markup'], $settings['options']['existing_og_css'], $settings['options']['subscribed']);
+
+    }
+  }
+
+  return;
+}
Index: supported/profile.inc
===================================================================
diff -u -p -N supported/profile.inc	17 Oct 2008 17:59:09 -0000
--- /dev/null
+++ supported/profile.inc
@@ -0,0 +1,54 @@
+<?php
+// $Id: $
+
+/**
+ * @file
+ * Import profile module properties.
+ */
+
+/**
+ * Implementation of hook_user_import_form_field_match().
+ */
+function profile_user_import_form_field_match() {
+
+  $fields = _user_import_profile('fid', 'title');
+  $options['profile'] = $fields;
+  return $options;
+}
+
+/**
+ * Implementation of hook_user_import_data().
+ */
+function profile_user_import_data($settings, $column_settings, $module, $field_id, $data, $column_id) {
+
+  if ($module!= 'profile') return;
+
+  return trim($data[$column_id]);
+}
+
+/**
+ * Implementation of hook_user_import_after_save().
+ */
+function profile_user_import_after_save($settings, $account, $password, $fields) {
+  // import info to profile
+  if (is_array($fields['profile'])) {
+      while (list ($fid, $data) = each ($fields['profile'])) {
+      	profile_user_import_save_profile($fid, $account->uid, trim($data[0]));
+      }
+  }
+
+  return;
+}
+
+function profile_user_import_save_profile($field, $uid, $value) {
+	$sql = db_query("SELECT value FROM {profile_values} WHERE fid = %d AND uid = %d", $field, $uid);
+	if ($row = db_fetch_object($sql)) {
+      $profile = db_query("UPDATE {profile_values} SET value = '%s' WHERE fid = %d AND uid = %d", $value, $field, $uid);		
+	}
+	else {
+      $profile = db_query("INSERT INTO {profile_values} (fid,uid,value) VALUES(%d,%d,'%s')", $field, $uid, $value);
+	}
+    return;
+}
+
+
Index: supported/subscribed.inc
===================================================================
diff -u -p -N 
--- /dev/null
+++ supported/subscribed.inc	17 Oct 2008 17:59:09 -0000
@@ -0,0 +1,98 @@
+<?php
+// $Id: $
+
+/**
+ * @file
+ * Import subscribed module properties.
+ */
+
+/**
+ * Implementation of hook_user_import_form_fieldsets().
+ */
+function subscribed_user_import_form_fieldset($import, $collapsed) {
+
+  if (module_exists('publication') && module_exists('schedule')) {
+
+    $publications = publication_select_publications('enewsletter');
+    if (empty($publications)) return;
+
+    $form['subscribed'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Subscriptions'),
+        '#collapsible' => TRUE,
+        '#collapsed' => $collapsed,
+        '#tree' => TRUE,
+    );
+
+    foreach ($publications as $publication) {
+
+      $type = $publication->type;
+
+      $form['subscribed'][$type] = array(
+          '#type' => 'fieldset',
+          '#title' => check_plain($type),
+      );
+
+    }
+
+    reset($publications);
+    $subscribed = $import['options']['subscribed'];
+
+    foreach ($publications as $publication) {
+
+      $options = array();
+      $schedules = schedule_select_schedules($type, $publication->publication_id);
+      $options[0] = t('No Subscription');
+
+      foreach ($schedules as $schedule) {
+        $options[ $schedule['schedule_id'] ] = $schedule['schedule_title'];
+      }
+
+      $subscription_default = empty($subscribed[$type][$publication->publication_id]) ? 0 : $subscribed[$type][$publication->publication_id][0];
+
+      $form['subscribed'][$type][$publication->publication_id][] = array(
+        '#type' => 'radios',
+        '#title' => check_plain($publication->title),
+        '#default_value' => $subscription_default,
+        '#options' => $options,
+        '#description' => check_plain($publication->description),
+      );
+
+    }
+  }
+
+  return $form;
+}
+
+/**
+ * Implementation of hook_user_import_after_save().
+ */
+function subscribed_user_import_after_save($settings, $account, $password, $fields) {
+
+  if (!module_exists('publication') || !module_exists('schedule') || !module_exists('identity_hash') || empty($settings['options']['subscribed'])) return;
+
+  $subscribed_settings = $settings['options']['subscribed'];
+  $uid = $account->uid;
+
+  if (is_array($subscribed_settings)) {
+
+    while (list($type, $type_subscriptions) = each($subscribed_settings)) {
+
+      $subscriptions = $type_subscriptions;
+
+      foreach ($type_subscriptions as $publication_id => $schedule) {
+        if (empty($schedule[0])) unset($subscriptions[$publication_id]);
+      }
+
+      $publications = publication_select_publications_and_terms($type);
+
+      if (!empty($publications) && !empty($subscriptions)) {
+        subscribed_set_subscriptions($type, $uid, $publications, $subscriptions);
+        subscribed_set_subscriptions_terms($type, $uid, $publications, $subscriptions);
+        identity_hash_set_hash($uid);
+      }
+
+    }
+  }
+  return;
+}
Index: supported/user.inc
===================================================================
diff -u -p -N supported/user.inc
--- /dev/null
+++ supported/user.inc	17 Oct 2008 17:59:09 -0000
@@ -0,0 +1,208 @@
+<?php
+// $Id: $
+
+/**
+ * @file
+ * Include user module properties.
+ */
+
+/**
+ * Implementation of hook_user_import_form_field_match().
+ */
+function user_user_import_form_field_match() {
+
+  $options = array();
+
+  $options['user']['email'] = t('Email Address *');
+  $options['user']['password'] = t('Password');
+  $options['user']['role'] = t('Role');
+  $options['user']['language'] = t('Language');
+  $options['user']['delete'] = t('Delete');
+
+  return $options;
+}
+
+
+/**
+ * Implementation of hook_user_import_form_fieldsets().
+ */
+function user_user_import_form_fieldset($import, $collapsed) {
+
+  $form = array();
+  user_user_import_edit_roles_fields($form, $import, $collapsed);
+  user_user_import_edit_email_fields($form, $import, $collapsed);
+
+  return $form;
+}
+
+/**
+ * Implementation of hook_user_import_data().
+ */
+function user_user_import_data($settings, $column_settings, $module, $field_id, $data, $column_id) {
+
+  if ($module != 'user') return;
+
+  if ($field_id == 'email') {
+    $value = trim($data[$column_id]);
+    _user_import_validate_email($value, $settings['options']['update_users']);
+  }
+
+  if ($field_id == 'password') {
+    $value = trim($data[$column_id]);
+  }
+
+  if ($field_id == 'role') {
+    $value = drupal_strtolower(trim($data[$column_id]));
+  }
+
+  if ($field_id == 'language') {
+    $value = drupal_strtolower(trim($data[$column_id]));
+  }
+
+  if ($field_id == 'delete') {
+    $value = drupal_strtolower(trim($data[$column_id]));
+  }
+
+  return $value;
+}
+
+/**
+ * Implementation of hook_user_import_pre_save().
+ */
+function user_user_import_pre_save($settings, $account, $password, $fields, $errors) {
+
+  $account_add['mail'] = $fields['user']['email'][0];
+
+  // get roles from csv
+  $role = $fields['user']['role'][0];
+  //check if role exists:
+
+  $rid = db_result(db_query("SELECT rid FROM {role} WHERE name = '%s'", $role));
+  if ($rid) {
+    $account_add['roles'][$rid] = $rid;
+  }
+  else {
+    // it doesn't exist, create it
+    db_query("INSERT INTO {role} (name) VALUES ('%s')", $role);
+    $rid = db_last_insert_id('role', 'rid');
+    $account_add['roles'][$rid] = $rid;
+  }
+    
+  if (empty($settings['options']['update_users'])) {
+
+    $account_add['timezone'] = '-18000';
+    $account_add['status'] = 1;
+    $account_add['init'] = $fields['user']['email'][0];
+    $account_add['pass'] = (empty($fields['user']['password'][0])) ? user_password() : $fields['user']['password'][0];
+    $account_add['language'] = $fields['user']['language'][0];
+
+    // get enabled roles
+    if (is_array($settings['roles'])) {
+      while (list ($rid, $role_set) = each ($settings['roles'])) {
+        if (!empty($role_set)) $account_add['roles'][$rid] = $rid;
+      }
+    }
+
+    if (!empty($settings['options']['activate'])) {
+      $account_add['access'] = time();
+      $account_add['login'] = time();
+    }
+
+    if ($settings['contact'] == 1) $account_add['contact'] = 1;
+  }
+
+  return $account_add;
+}
+
+
+function user_user_import_edit_roles_fields(&$form, $import, $collapsed) {
+
+  $roles_data = user_roles();
+  // remove 'anonymous user' option
+  while (list ($rid, $role_name) = each ($roles_data)) {
+      if ($role_name != 'anonymous user' && $role_name != 'authenticated user') $roles[$rid] = $role_name;
+  }
+
+  // roles selected
+  if ( !empty($import['roles']) ) {
+      foreach ($import['roles'] as $rid) {
+          if ($rid != 0) $roles_selected[] = $rid;
+      }
+  }
+
+  if ( empty($roles_selected) ) $roles_selected[] = 2;
+
+  $form['role_selection'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Role Assign'),
+      '#description' => t("Select which role(s) imported users should be assigned. The role 'authenticated user' is assigned automatically."),
+      '#weight' => -80,
+      '#collapsible' => TRUE,
+      '#collapsed' => $collapsed,
+  );
+
+  $form['role_selection']['roles'] = array(
+      '#type' => 'checkboxes',
+      '#options' => $roles,
+      '#default_value' => $roles_selected,
+  );
+
+  return;
+}
+
+function user_user_import_edit_email_fields(&$form, $import, $collapsed) {
+
+  $form['email_message'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Email Message'),
+    '#description' => t('Welcome message to be sent to imported users. Leave blank to use the default !message.<br /><strong>Warning</strong>: if you copy and paste directly from Word some characters may get garbled.', array('!message' => l('message', 'admin/user/settings'))),
+    '#collapsible' => TRUE,
+    '#collapsed' => $collapsed,
+  );
+
+  $form['email_message']['subject'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Message Subject'),
+    '#default_value' => $import['options']['subject'],
+    '#description' => t('Customize the subject of the welcome e-mail, which is sent to imported members.') .' '. t('Available variables are:') .' !username, !site, !password, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url'. $profile_string .'.',
+  );
+
+  $form['email_message']['message'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Message'),
+    '#default_value' => $import['options']['message'],
+    '#description' => t('Customize the body of the welcome e-mail, which is sent to imported members.') .' '. t('Available variables are:') .' !username, !site, !password, !uri, !uri_brief, !mailto, !login_uri, !edit_uri, !login_url'. $profile_string .'.',
+  );
+
+  $form['email_message']['message_format'] = array(
+    '#type' => 'radios',
+    '#title' => t('Email Format'),
+    '#default_value' => empty($import['options']['message_format']) ? 0 : $import['options']['message_format'],
+    '#options' => array(t('Plain Text'), t('HTML')),
+  );
+
+  $form['email_message']['message_css'] = array(
+    '#type' => 'textarea',
+    '#title' => t('CSS'),
+    '#default_value' => $import['options']['message_css'],
+    '#description' => t('Use if sending HTML formated email.'),
+  );
+
+  return;
+}
+
+
+function _user_import_validate_email($email = NULL, $duplicates_allowed = FALSE) {
+  if (!$email) {
+    user_import_errors(t('no email'));
+  }
+  elseif (!valid_email_address($email)) {
+    user_import_errors(t('invalid email'));
+  }
+  // Handle duplicate emails.
+  elseif (!$duplicates_allowed && _user_import_existing_uid($email)) {
+    user_import_errors(t('duplicate email'));
+  }
+  
+  return;
+}
Index: supported/user_import.inc
===================================================================
diff -u -p -N supported/user_import.inc
--- /dev/null
+++ supported/user_import.inc	17 Oct 2008 17:59:09 -0000
@@ -0,0 +1,300 @@
+<?php
+// $Id: $
+
+/**
+ * @file
+ * Import users from a comma separated file (csv).
+ */
+
+/**
+ * Implementation of hook_user_import_form_fieldsets().
+ * Add fieldsets to an import settings form.
+ */
+function user_import_user_import_form_fieldset($import, $collapsed) {
+
+  $form = array();
+  _user_import_edit_template_fields($form, $import);
+  _user_import_edit_settings_fields($form, $import, $collapsed);
+  _user_import_edit_remove_fields($form, $import);
+
+  return $form;
+}
+
+
+/**
+ * Implementation of hook_user_import_after_save().
+ */
+function user_import_user_import_after_save($settings, $account, $password, $fields) {
+
+  if (!empty($settings['send_email'])) _user_import_send_email($account, $password, $fields, $settings['options']['subject'], $settings['options']['message'], $settings['options']['message_format'], $settings['options']['message_css'], $settings['options']['subscribed']);
+
+  return;
+}
+
+// Send email when account is created
+function _user_import_send_email($account, $password, $profile, $subject, $body, $format, $css, $subscribed) {
+
+  global $base_url;
+  $from = variable_get('site_mail', ini_get('sendmail_from'));
+
+  $options['absolute'] = TRUE;
+
+  $variables = array(
+    '!username' => $account->name,
+    '!uid' => $account->uid,
+    '!site' => variable_get('site_name', 'drupal'),
+    '!login_url' => user_pass_reset_url($account),
+    '!password' => $password,
+    '!uri' => $base_url,
+    '!uri_brief' => drupal_substr($base_url, drupal_strlen('http://')),
+    '!mailto' => $account->mail,
+    '!date' => format_date(time()),
+    '!login_uri' => url('user', $options),
+    '!edit_uri' => url('user/'. $account->uid .'/edit', $options),
+  );
+
+  _user_import_publication_email($variables, $account, $subscribed, $format);
+
+  // import info to profile
+  if (module_exists('profile') && is_array($profile)) {
+    $profile_name = _user_import_profile('fid', 'name');
+    while (list ($fid, $field_name) = each ($profile_name)) {
+      $variables['!'. $field_name] = $profile[$fid];
+    }
+  }
+
+  $subject = (empty($subject)) ? _user_mail_text('welcome_subject', $variables) : strtr($subject, $variables);
+  $subject = mime_header_encode($subject);
+  $body = (empty($body)) ? _user_mail_text('welcome_body', $variables) : strtr($body, $variables);
+  $body = str_replace("\r", '', $body);
+
+  $header = "From: $from\n";
+  $header .= "Reply-to: $from\n";
+  $header .= "X-Mailer: Drupal\n";
+  $header .= "Return-path: $from\n";
+  $header .= "Errors-to: $from\n";
+  $header .= 'MIME-Version: 1.0';
+  $header .= "\n";
+
+  if ($format == 1) {
+
+    $header .= 'Content-Type: text/html; charset=UTF-8; Content-transfer-encoding: 8Bit';
+
+    $body_head = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+              <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+              <head>
+              <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />';
+
+    if (!empty($css)) $body_head .= '<style type="text/css">'. check_plain($css) .'</style>';
+
+    $body = $body_head .'</head><body>'. $body .'<body></html>';
+
+  }
+  else {
+    $header .= 'Content-Type: text/plain; charset=UTF-8; format=flowed Content-transfer-encoding: 8Bit';
+  }
+
+  //mail($account->mail, $subject, $body, $header);
+  return;
+}
+
+function _user_import_edit_settings_fields(&$form, $import, $collapsed) {
+
+  $form['optional'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Options'),
+      '#weight' => -85,
+      '#collapsible' => TRUE,
+      '#collapsed' => $collapsed,
+  );
+
+  $form['optional']['update_users'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Update Existing Users'),
+      '#default_value' => $import['options']['update_users'],
+      '#description' => t('If the email address of a user being imported already exists, update the existing user details with the imported data.'),
+  );
+
+  $form['optional']['first_line_skip'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Ignore First Line'),
+      '#default_value' => $import['first_line_skip'],
+      '#description' => t('If the first line is the names of the data columns, set to ignore first line.'),
+  );
+
+  $form['optional']['contact'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Contact'),
+      '#default_value' => $import['contact'],
+      '#description' => t("Set each user's personal contact form to 'allowed'."),
+  );
+
+  $form['optional']['send_email'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Send Email'),
+    '#default_value' => $import['send_email'],
+    '#description' => t('Send email to users when their account is created.'),
+  );
+
+  $form['optional']['username_space'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Username Space'),
+      '#default_value' => $import['username_space'],
+      '#description' => t("Include spaces in usernames, e.g. 'John' + 'Smith' => 'John Smith'."),
+  );
+
+  $form['optional']['activate'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Activate Accounts'),
+      '#default_value' => $import['options']['activate'],
+      '#description' => t("User accounts will not be visible to other users until their owner logs in. Select this option to make all imported user accounts visible."),
+  );
+
+  return;
+}
+
+function _user_import_edit_template_fields(&$form, $import) {
+
+  // settings template update controls
+  if (empty($import['name'])) {
+
+     // new settings template save controls
+
+      $form['save'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Save Settings'),
+          '#description' => t('Save settings for re-use on other imports.'),
+          '#weight' => 90,
+          '#collapsible' => TRUE,
+          '#collapsed' => FALSE,
+      );
+
+      $form['save']['name'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Settings Name'),
+          '#size' => 26,
+          '#maxlength' => 25,
+          '#description' => t('Name to identify these settings by.'),
+      );
+
+      $form['save'][] = array(
+          '#type' => 'submit',
+          '#value' => t('Save'),
+      );
+
+  }
+  else {
+
+      $form['save'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Saved Settings'),
+          '#description' => t("If changes have neen made to the settings since they where last saved you can update the saved template, or save them as a new template."),
+          '#weight' => 90,
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+      );
+
+      $form['save']['name'] = array(
+          '#type' => 'value',
+          '#value' => $import['name']
+      );
+
+      $form['save']['update'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Update'),
+          '#description' => t("Update '%name' settings template", array('%name' => $import['name'])),
+      );
+
+      $form['save']['update']['submit'] = array(
+          '#type' => 'submit',
+          '#value' => t('Update'),
+      );
+
+      $form['save']['new'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Create New'),
+          '#description' => t("Save as new settings template"),
+      );
+
+      $form['save']['new']['new_name'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Save As New'),
+          '#size' => 30,
+          '#maxlength' => 25,
+          '#description' => t('Name to identify these settings by.'),
+      );
+
+      $form['save']['new'][] = array(
+          '#type' => 'submit',
+          '#value' => t('Save As New'),
+      );
+
+  }
+
+  return;
+}
+
+
+function _user_import_edit_remove_fields(&$form, $import) {
+
+  $form['remove'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Use Different CSV File'),
+      '#description' => t('Remove file to use a different file. All settings on this page will be deleted.'),
+      '#weight' => -100,
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+  );
+
+  $form['remove']['file'] = array(
+      '#type' => 'item',
+      '#title' => t('Uploaded file'),
+      '#value' => $import['filename']
+  );
+
+  $form['remove']['submit'] = array(
+      '#type' => 'submit',
+      '#value' => t('Remove file')
+  );
+
+  return;
+}
+
+function _user_import_publication_email(&$variables, $account, $subscribed, $format) {
+
+  if (!module_exists('publication') || !module_exists('schedule') || !module_exists('identity_hash')) {
+    return;
+  }
+
+
+
+  $id_hash = identity_hash_select_hash($account->uid);
+  $variables['!id_hash'] = $id_hash->hash;
+
+  while (list($type, $subscriptions) = each($subscribed)) {
+
+    while (list($publication_id, $shedule) = each($subscriptions)) {
+
+      if (!empty($shedule[0])) {
+
+        $publication = publication_select_publications($type, $publication_id);
+
+        $update_link = url('subscribed/preferences/'. $publication_id .'/'. $id_hash->hash, NULL, NULL, TRUE);
+        $unsubscribe_link = url('subscribed/delete/'. $publication_id .'/'. $id_hash->hash, NULL, NULL, TRUE);
+
+        if ($format == 1) {
+
+          $variables['!subscribed_links'] .= '<strong>'. $publication->title .'</strong><br />'.
+          '<a href="'. $update_link .'">'. t('Update Preferences') .'</a> | <a href="'. $unsubscribe_link .'">'. t('Unsubscribe') .'</a><br />';
+
+        }
+        else {
+
+          $variables['!subscribed_links'] .= $publication->title .'\n'.
+          ' - '. t('Update Preferences') .' '. $update_link .'\n'.
+          ' - '. t('Unsubscribe') .' '. $unsubscribe_link .'\n';
+        }
+      }
+    }
+  }
+}
Index: supported/watchdog.inc
===================================================================
diff -u -p -N supported/watchdog.inc
--- /dev/null
+++ supported/watchdog.inc	17 Oct 2008 17:59:09 -0000
@@ -0,0 +1,17 @@
+<?php
+// $Id: $
+
+/**
+ * @file
+ * Import watchdog properties.
+ */
+
+/**
+ * Implementation of hook_user_import_after_save().
+ */
+function watchdog_user_import_after_save($settings, $account, $password, $fields) {
+
+  watchdog('user', 'New user: %name %email.', array('%name' => theme('placeholder', check_plain($account->name)), '%email' => theme('placeholder', '<'. check_plain($account->mail) .'>')), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
+
+  return;
+}
\ No newline at end of file
Index: user_import.csv
===================================================================
diff -u -p -N user_import.csv
--- /dev/null
+++ b/user_import.csv	17 Oct 2008 17:59:09 -0000
@@ -0,0 +1,3 @@
+"8ae33f9f-2f08-4241-8a6e-00124f53e8a5","barco","be682ea9-1069-4207-80ae-00003b7ea779","Jan","Janssens","jan.janssens@abc.be","+32 1 234567","1","1","Algemeen directeur","no"
+"8ae33f9f-2f08-4241-8a6e-00124f53e8a5","belgacom","c021ce0e-c59e-445d-9199-0013a262edae","Pierre","Dupont","pierre.dupont@abc.be","+32 1 234568","2","1","ICT Director","no"
+"8ae33f9f-2f08-4241-8a6e-00124f53e8a5","belgacom","D6768687-c556-4887-665b-678676768678","Eliane","Franssen","eliane.franssen@abc.be","+32 1 234568","2","2","Responsable Marketing","no"
Index: user_import.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/user_import/user_import.info,v
retrieving revision 1.3
diff -u -p -r1.3 user_import.info
--- user_import.info	23 Jul 2007 22:55:10 -0000	1.3
+++ user_import.info	17 Oct 2008 17:59:09 -0000
@@ -2,11 +2,9 @@
 name = User Import
 description = Import users into Drupal from a CSV file.
-version = "$Name:  $"
-
-
-
-
-; Information added by drupal.org packaging script on 2007-03-13
-version = "5.x-1.2-beta"
+version = "$Name: DRUPAL-6--2 $"
+; Information added by drupal.org packaging script on 2008-05-16
+version = "6.x-2.x-dev"
 project = "user_import"
+datestamp = "1210897123"
+core = 6.x
 
Index: user_import.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/user_import/user_import.install,v
retrieving revision 1.6
diff -u -p -r1.6 user_import.install
--- user_import.install	23 Jul 2007 22:55:10 -0000	1.6
+++ user_import.install	17 Oct 2008 17:59:09 -0000
@@ -3,6 +3,147 @@
 
 /**
- * Implementation of hook_install()
+ * @file
+ * Import users from a comma separated file (csv).
+ */
+
+/**
+ * Implementation of hook_schema().
+ */
+function user_import_schema() {
+$schema['user_import'] = array(
+    'fields' => array(
+      'import_id' => array(
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'disp-width' => '10'
+      ),
+      'name' => array(
+        'type' => 'varchar',
+        'length' => '25',
+        'not null' => TRUE,
+        'default' => ''
+      ),
+      'filename' => array(
+        'type' => 'varchar',
+        'length' => '50',
+        'not null' => TRUE,
+        'default' => ''
+      ),
+      'oldfilename' => array(
+        'type' => 'varchar',
+        'length' => '50',
+        'not null' => TRUE,
+        'default' => ''
+      ),
+      'filepath' => array(
+        'type' => 'text',
+        'size' => 'small',
+        'not null' => TRUE
+      ),
+      'started' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'disp-width' => '11'
+      ),
+      'pointer' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'disp-width' => '10'
+      ),
+      'processed' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'disp-width' => '10'
+      ),
+      'valid' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'disp-width' => '10'
+      ),
+      'first_line_skip' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'disp-width' => '1'
+      ),
+      'contact' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'disp-width' => '1'
+      ),
+      'username_space' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'disp-width' => '1'
+      ),
+      'send_email' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'disp-width' => '1'
+      ),
+      'field_match' => array(
+        'type' => 'text',
+        'size' => 'big',
+        'not null' => TRUE
+      ),
+      'roles' => array(
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+        'default' => ''
+      ),
+      'options' => array(
+        'type' => 'text',
+        'size' => 'big',
+        'not null' => TRUE
+      ),
+      'setting' => array(
+        'type' => 'varchar',
+        'length' => '10',
+        'not null' => TRUE,
+        'default' => ''
+      )
+    ),
+    'primary key' => array('import_id'),
+  );
+
+  $schema['user_import_errors'] = array(
+    'fields' => array(
+      'import_id' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'disp-width' => '10'
+      ),
+      'data' => array(
+        'type' => 'text',
+        'size' => 'big',
+        'not null' => TRUE
+      ),
+      'errors' => array(
+        'type' => 'varchar',
+        'length' => '25',
+        'not null' => TRUE,
+        'default' => ''
+      )
+    ),
+    'indexes' => array(
+      'import_id' => array('import_id')
+    ),
+  );
+  return $schema;
+}
+
+/**
+ * Implementation of hook_install().
  *
  * This will automatically install the database tables for the user import module for both the MySQL and PostgreSQL databases.
  *
@@ -12,57 +153,13 @@
  * and will need to be removed.
  */
 function user_import_install() {
-  switch ($GLOBALS['db_type']) {
-    case 'mysqli':
-    case 'mysql':
-      $query1 = db_query("CREATE TABLE IF NOT EXISTS {user_import} (
-                        import_id int(10) unsigned NOT NULL auto_increment,
-                        name varchar(25) NOT NULL default '',
-                        filename varchar(50) NOT NULL default '',
-                        oldfilename varchar(50) NOT NULL default '',
-                        filepath tinytext NOT NULL,
-                        started int(11) NOT NULL default '0',
-                        pointer int(10) NOT NULL default '0',
-                        processed int(10) NOT NULL default '0',
-                        valid int(10) NOT NULL default '0',
-                        first_line_skip int(1) NOT NULL default '0',
-                        contact int(1) NOT NULL default '0',
-                        username_space int(1) NOT NULL default '0',
-                        send_email int(1) NOT NULL default '0',
-                        field_match longtext NOT NULL,
-                        roles varchar(255) NOT NULL default '',
-                        options longtext NOT NULL,
-                        setting varchar(10) NOT NULL default '',
-                        PRIMARY KEY  (import_id)
-                        ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
-  
-      $query2 = db_query("CREATE TABLE IF NOT EXISTS {user_import_errors} (
-                        import_id int(10) NOT NULL default '0',
-                        data longtext NOT NULL,
-                        error varchar(25) NOT NULL default '',
-                        KEY import_id (import_id)
-                        ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
-
-      if ($query1 && $query2) {
-        $created = TRUE;
-      }
-      break;      
-  }
-  
-  if ($created) {
-    drupal_set_message(t('User Import module installed successfully.'));
-  }
-  else {
-    drupal_set_message(t('Table installation for the User Import module was unsuccessful. The tables may need to be installed by hand. See user_import.install file for a list of the installation queries.'), 'error');
-  }
-  
-  return;
+  drupal_install_schema('user_import');
 }
 
 function user_import_update_1() {
 
     _system_update_utf8(array('user_import', 'user_import_errors'));
-    
+
   return;
 }
 
@@ -75,17 +172,23 @@ function user_import_update_2() {
 function user_import_update_3() {
   $ret = array();
   $ret[] = update_sql("ALTER TABLE {user_import} CHANGE iid import_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT");
-  $ret[] = update_sql("ALTER TABLE {user_import} CHANGE first_line first_line_skip INT(10) UNSIGNED NOT NULL default '0'");  
+  $ret[] = update_sql("ALTER TABLE {user_import} CHANGE first_line first_line_skip INT(10) UNSIGNED NOT NULL default '0'");
   $ret[] = update_sql("ALTER TABLE {user_import_errors} CHANGE iid import_id INT(10) UNSIGNED NOT NULL default '0'");
   return $ret;
 }
 
+function user_import_update_4() {
+  $ret = array();
+  $ret[] = update_sql("ALTER TABLE {user_import_errors} CHANGE error errors longtext NOT NULL");
+  return $ret;
+}
+
 /**
-* Implementation of hook_uninstall().
-*/
+ * Implementation of hook_uninstall().
+ */
 function user_import_uninstall() {
-  db_query('DROP TABLE {user_import}');
-  db_query('DROP TABLE {user_import_errors}');
+  drupal_uninstall_schema('user_import');
+  drupal_uninstall_schema('user_import_errors');
   variable_del('user_import_settings');
   variable_del('user_import_max');
   variable_del('user_import_line_max');
Index: user_import.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/user_import/user_import.module,v
retrieving revision 1.19
diff -u -p -r1.19 user_import.module
--- user_import.module	23 Jul 2007 22:55:10 -0000	1.19
+++ user_import.module	17 Oct 2008 17:59:09 -0000
@@ -7,14 +7,14 @@
  */
 
 /**
- * - - - - - - - -  HOOKS - - - - - - - - 
+ * - - - - - - - -  HOOKS - - - - - - - -
  */
 
 /**
  * Implementation of hook_help().
  */
-function user_import_help($section) {
-  switch ($section) {
+function user_import_help($path, $arg) {
+  switch ($path) {
     case 'admin/user/user_import':
       return t("Import users from a comma separated file (csv). Click 'Import' to start a new import.");
   }
@@ -24,102 +24,143 @@ function user_import_help($section) {
  * Implementation of hook_perm().
  */
 function user_import_perm() {
-  return array('import users');
+  return array('import users', 'limited user import');
 }
 
 /**
  * Implementation of hook_menu().
  */
-function user_import_menu($may_cache) {
-  
+function user_import_menu() {
+
   global $user;
   $items = array();
-  
-     if ($may_cache) {     
-     
-        $items[] = array(
-            'path' => 'admin/user/user_import', 
-            'title' => t('User Imports'), 
-            'callback' => 'user_import_list',
-            'description' => t('Import users from a comma separated file (csv).'),
-            'access' => user_access('import users'),
-            );
-        $items[] = array(
-            'path' => 'admin/user/user_import/list', 
-            'title' => t('List Imports'), 
-            'access' => user_access('import users'),
-            'weight' => -10,
-            'type' => MENU_DEFAULT_LOCAL_TASK
-            );
-        $items[] = array(
-          'path' => 'admin/user/user_import/add', 
-          'title' => t('Import'),
-          'callback' => 'user_import_preferences',
-          'access' => user_access('import users'),
-          'weight' => -5,
-          'type' => MENU_LOCAL_TASK
-        );
-        $items[] = array(
-          'path' => 'admin/user/user_import/continue', 
-          'title' => t('Continue'),
-          'callback' => 'user_import_continue',
-          'access' => user_access('import users'),
-          'type' => MENU_CALLBACK
-        );
-        $items[] = array(
-          'path' => 'admin/user/user_import/import', 
-          'title' => t('Import'),
-          'callback' => 'user_import_import',
-          'access' => user_access('import users'),
-          'type' => MENU_CALLBACK
-        );
-        $items[] = array(
-          'path' => 'admin/user/user_import/delete', 
-          'title' => t('Delete Import'),
-          'callback' => 'user_import_delete',
-          'access' => user_access('import users'),
-          'type' => MENU_CALLBACK
-        );
-        
-        
-        $items[] = array(
-          'path' => 'admin/user/user_import/configure', 
-          'title' => t('Configure'),
-          'callback' => 'drupal_get_form',
-          'callback arguments' => array('user_import_configure_form'),
-          'access' => user_access('import users'),
-          'type' => MENU_LOCAL_TASK
-        );
-    }
+
+  $items['admin/user/user_import'] = array(
+    'title' => 'User Imports',
+    'page callback' => 'user_import_list',
+    'description' => 'Import users from a comma separated file (csv).',
+    'access arguments' => array('import users'),
+  );
+  $items['admin/user/user_import/list'] = array(
+    'title' => 'List Imports',
+    'access arguments' => array('import users'),
+    'weight' => -10,
+    'type' => MENU_DEFAULT_LOCAL_TASK
+  );
+  $items['admin/user/user_import/add'] = array(
+    'title' => 'Import',
+    'page callback' => 'user_import_preferences',
+    'access arguments' => array('import users'),
+    'weight' => -5,
+    'type' => MENU_LOCAL_TASK
+  );
+  $items['admin/user/user_import/continue'] = array(
+    'title' => 'Continue',
+    'page callback' => 'user_import_continue',
+    'access arguments' => array('import users'),
+    'type' => MENU_CALLBACK
+  );
+  $items['admin/user/user_import/import'] = array(
+    'title' => 'Import',
+    'page callback' => 'user_import_import',
+    'access arguments' => array('import users'),
+    'type' => MENU_CALLBACK
+  );
+  $items['admin/user/user_import/delete'] = array(
+    'title' => 'Delete Import',
+    'page callback' => 'user_import_delete',
+    'access arguments' => array('import users'),
+    'type' => MENU_CALLBACK
+  );
+  $items['admin/user/user_import/configure'] = array(
+    'title' => 'Configure',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('user_import_configure_form'),
+    'access arguments' => array('import users'),
+    'type' => MENU_LOCAL_TASK
+  );
+  $items['user_import'] = array(
+    'title' => 'Import Users',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('user_import_preconfigured'),
+    'access arguments' => array('limited user import'),
+  );
+  $items['user_import/delete'] = array(
+    'title' => 'Remove Info',
+    'page callback' => 'user_import_limited_delete',
+    'type' => MENU_CALLBACK,
+    'access arguments' => array('limited user import'),
+  );
+  $items['user_import/errors'] = array(
+    'title' => 'Import Errors',
+    'page callback' => 'user_import_limited_errors',
+    'type' => MENU_CALLBACK,
+    'access arguments' => array('limited user import'),
+  );
 
   return $items;
 }
 
 function user_import_cron() {
-    
-    $imports = _user_import_settings_select();    
-    if (!$imports) return;
-    
+
+  $imports = _user_import_settings_select();
+  
+  if (is_array($imports)) {
     foreach ($imports as $import) {
-        
-        if ($import['setting'] == 'test' || $import['setting'] == 'import') _user_import_process($import);
+      if ($import['setting'] == 'test' || $import['setting'] == 'import') _user_import_process($import);
     }
-        
-    return;
+  }
+  
+  $file = variable_get('user_import_file', 'user_import.csv');
+  $path = drupal_get_path('module', 'user_import');
+
+  if (file_exists($path.'/'.$file)) {
+    $settings_template = variable_get('user_import_settings', '2');
+    $template = _user_import_settings_select($settings_template);
+    $form_state['values']['filename'] = $file;
+    $form_state['values']['oldfilename'] = $file;
+    $form_state['values']['filepath'] = $path.'/'.$file;
+
+    // create import setting
+    $import = _user_import_settings_save($form_state['values']);
+    $import['first_line_skip'] = $template['first_line_skip'];
+    $import['contact'] = $template['contact'];
+    $import['username_space'] = $template['username_space'];
+    $import['send_email'] = $template['send_email'];
+    $import['field_match'] = $template['field_match'];
+    $import['roles'] = $template['roles'];
+    $import['options'] = $template['options'];
+    $import['update_users'] = 1;
+    $import['activate'] = 1;
+    $import['setting'] = 'import';
+
+    $filepath = file_move($import['filepath'], file_directory_path() .'/'. $import['filename']);
+    if (!empty($template['og_id'])) $import['groups'][$template['og_id']] = $template['og_id'];
+
+    $import = _user_import_settings_save($import);
+
+    $import['save']['update'] = NULL;
+    $import['import_template_id'] = NULL;
+    $import['save']['name'] = NULL;
+
+    _user_import_process($import);
+  }
+
+  return;
 }
 
-// - - - - - - - -  FORMS - - - - - - - - 
+// - - - - - - - -  FORMS - - - - - - - -
+
+function user_import_configure_form() {
 
-function user_import_configure_form() { 
-        
-    $form['email'] = array(
+    $form['performance'] = array(
         '#type' => 'fieldset',
-        '#title' => t('Email'),
+        '#title' => t('Performance'),
         '#collapsible' => TRUE,
         '#collapsed' => TRUE,
     );
 
-    $form['email']['user_import_max'] = array(
+    $form['performance']['user_import_max'] = array(
         '#type' => 'textfield',
         '#title' => t('Maximum Users/Process'),
         '#default_value' => variable_get('user_import_max', 250),
@@ -127,8 +168,8 @@ function user_import_configure_form() { 
         '#maxlength' => 10,
         '#description' => t('Maximum number of users to import each time the file is processed, useful for controling the rate at which emails are sent out.'),
     );
-    
-    $form['email']['user_import_line_max'] = array(
+
+    $form['performance']['user_import_line_max'] = array(
         '#type' => 'textfield',
         '#title' => t('Maximum length of line'),
         '#default_value' =>  variable_get('user_import_line_max', 1000),
@@ -136,45 +177,42 @@ function user_import_configure_form() { 
         '#maxlength' => 10,
         '#description' => t('The default is set at 1,000 characters, if a line in your csv is longer than this you should set a higher maximum here. Setting higher maximums will slow down imports.'),
     );
-    
-    
+
+
     $saved_templates = _user_import_settings_select(NULL, 'GET TEMPLATES');
-    
+
     if (!empty($saved_templates)) {
- 
+
         $form['settings_templates'] = array(
             '#type' => 'fieldset',
             '#title' => t('Settings Templates'),
             '#collapsible' => TRUE,
             '#collapsed' => TRUE,
         );
-        
+
         $templates_list = array('-- none --');
-        
+
         foreach ($saved_templates AS $template) {
             $templates_list[$template['import_id']] = $template['name'];
             $templates_delete[$template['import_id']] = $template['name'];
         }
-        
-        $form['settings_templates']['user_import_settings'] = array( 
+        $form['settings_templates']['user_import_settings'] = array(
             '#type' => 'select',
             '#title' => t('Default Settings'),
             '#description' => t('Select if you want to use a previously saved set of settings as default for all imports.'),
             '#default_value' => variable_get('user_import_settings', 0),
             '#options' => $templates_list,
         );
-
-        
         $form['settings_templates']['templates'] = array(
             '#type' => 'checkboxes',
             '#title' => t('Delete Templates'),
             '#options' => $templates_delete,
         );
-    
+
     }
-    
+
     $check_usernames = variable_get('user_export_checked_usernames', 0);
-    
+
     $form['check_names'] = array(
         '#type' => 'fieldset',
         '#title' => t('Check Existing Usernames'),
@@ -182,514 +220,722 @@ function user_import_configure_form() { 
         '#collapsed' => empty($check_usernames) ? TRUE : FALSE,
         '#description' => t('Previous versions of User Import module may have created incorrect usernames, use this feature to check.'),
     );
-    
+
     if (!empty($check_usernames)) {
-        
+
         variable_set('user_export_checked_usernames', 0);
         $errors = user_import_usernames_invalid();
-        
+
         $form['check_names'][] = array(
             '#value' => $errors,
         );
-        
         $form['check_names'][] = array(
-            '#type' => 'submit', 
+            '#type' => 'submit',
             '#value' => t('Check'),
         );
-        
-        if ($errors != '<p><strong>' . t('All usernames are OK.') . '</strong></p>') {
+
+        if ($errors != '<p><strong>'. t('All usernames are OK.') .'</strong></p>') {
             $form['check_names'][] = array(
-                '#type' => 'submit', 
+                '#type' => 'submit',
                 '#value' => t('Delete'),
             );
         }
-        
-        
-        
-    } else {
-
+    }
+    else {
         $form['check_names'][] = array(
-            '#type' => 'submit', 
+            '#type' => 'submit',
             '#value' => t('Check'),
         );
     }
 
 
     $form['submit'] = array(
-        '#type' => 'submit', 
+        '#type' => 'submit',
         '#value' => t('Save'),
         );
-    
+
     return $form;
 }
-function user_import_configure_form_validate($form_id, &$form) {
 
-    if (is_numeric($form['user_import_max'])) {
-        if ($form['user_import_max'] < 10) form_set_error('user_import_max', t("Value should be at least 10."));       
-    } 
+function user_import_configure_form_validate($form, &$form_state) {
+
+    if (is_numeric($form_state['values']['user_import_max'])) {
+        if ($form_state['values']['user_import_max'] < 10) form_set_error('user_import_max', t("Value should be at least 10."));
+    }
     else {
         form_set_error('user_import_max', t('Value must be a number.'));
     }
-    
-    if (is_numeric($form['user_import_line_max'])) {
-        if ($form['user_import_line_max'] < 1000) form_set_error('user_import_line_max', t("Value must be higher than 1000."));
-        if ($form['user_import_line_max'] > 1000000) form_set_error('user_import_line_max', t("Value must be lower than 1,000,000."));
-    } 
+
+    if (is_numeric($form_state['values']['user_import_line_max'])) {
+        if ($form_state['values']['user_import_line_max'] < 1000) form_set_error('user_import_line_max', t("Value must be higher than 1000."));
+        if ($form_state['values']['user_import_line_max'] > 1000000) form_set_error('user_import_line_max', t("Value must be lower than 1,000,000."));
+    }
     else {
         form_set_error('user_import_line_max', t('Value must be a number.'));
     }
-    
+
     return;
 }
-function user_import_configure_form_submit($form_id, $form_values) { 
 
-    settype($form_values['user_import_max'], 'integer');
-    settype($form_values['user_import_line_max'], 'integer');
-    variable_set('user_import_max', $form_values['user_import_max']);
-    variable_set('user_import_line_max', $form_values['user_import_line_max']);
-    variable_set('user_import_settings', $form_values['user_import_settings']);
-    
-    if (!empty($form_values['templates'])) {
+function user_import_configure_form_submit($form, &$form_state) {
+
+    settype($form_state['values']['user_import_max'], 'integer');
+    settype($form_state['values']['user_import_line_max'], 'integer');
+    variable_set('user_import_max', $form_state['values']['user_import_max']);
+    variable_set('user_import_line_max', $form_state['values']['user_import_line_max']);
+    variable_set('user_import_settings', $form_state['values']['user_import_settings']);
 
-        foreach ($form_values['templates'] as $import_id) {
-            
+    if (!empty($form_state['values']['templates'])) {
+        foreach ($form_state['values']['templates'] as $import_id) {
             if (!empty($import_id)) {
-            
                 $template = _user_import_settings_select($import_id);
                 if (!empty($deleted)) $deleted .= ', ';
-                $deleted .= $template['name'];       
+                $deleted .= $template['name'];
                 _user_import_settings_deletion($import_id);
             }
         }
     }
-    
+
     if (!empty($deleted)) drupal_set_message(t('Settings templates deleted: @deleted', array('@deleted' => $deleted)));
-    
-    if ($form_values[op] == t('Check')) {
-       variable_set('user_export_checked_usernames', 1);
-       return;
-    }
-    
-    if ($form_values[op] == t('Delete')) {
-       user_import_usernames_invalid(TRUE);
+
+    if ($form_state['values']['op'] == t('Check')) {
+      variable_set('user_export_checked_usernames', 1);
+      return;
     }
-    
+
+    if ($form_state['values']['op'] == t('Delete')) {
+      user_import_usernames_invalid(TRUE);
+    }
+
     drupal_set_message(t('Configuration settings have been saved.'));
     drupal_goto('admin/user/user_import');
 }
 
-function user_import_add_form($import_id = NULL) {
+function user_import_add_form($form_state, $import_id = NULL) {
+  $form = array();
+  $ftp_files = _user_import_ftp_files();
+  user_import_add_file_form($form, $ftp_files);
+
+  $settings = _user_import_settings_select(NULL, 'get saved');
+
+  if ($settings) {
+    $saved_settings = array(t('-- none --'));
+    foreach ($settings AS $settings_set) {
+      $saved_settings[$settings_set['import_id']] = $settings_set['name'];
+    }
+
+    $form['import_template_select'] = array(
+      '#type' => 'select',
+      '#title' => t('Saved Settings'),
+      '#description' => t('Select if you want to use a previously saved set of settings.'),
+      '#default_value' => variable_get('user_import_settings', 0),
+      '#options' => $saved_settings,
+    );
+  }
 
-    $ftp_files = _user_import_ftp_files();
-    
-    if (!empty($ftp_files)) {
-        
-        $form['browser'] = array(
-            '#type' => 'fieldset',
-            '#title' => t('Browser Upload'),
-            '#collapsible' => TRUE,
-            '#description' => t("Upload a CSV file."),
-        );
-        
-        if (function_exists('file_upload_max_size')) $file_size = t('Maximum file size: !size MB.', array('!size' => file_upload_max_size()));
+  $form['next'] = array(
+    '#type' => 'submit',
+    '#value' => t('Next')
+  );
 
-        $form['browser']['file_upload'] = array(
-            '#type' => 'file',
-            '#title' => t('CSV File'),
-            '#size' => 40,
-            '#description' => t('Select the CSV file to be imported. ') . $file_size,
-        );
+  // Set form parameters so we can accept file uploads.
+  $form['#attributes'] = array('enctype' => 'multipart/form-data');
 
-        $form['ftp'] = array(
-            '#type' => 'fieldset',
-            '#title' => t('FTP Upload'),
-            '#collapsible' => TRUE,
-            '#collapsed' => TRUE,
-            '#description' => t("Any files uploaded to the 'user_import' directory using FTP can be selected for import here. Useful if the import file is too large for upload via the browser."),
-        );
-        
-         $form['ftp']['file_ftp'] = array(
-              '#type' => 'radios',
-              '#title' => t('Files'),
-              '#default_value' => 0,
-              '#options' => $ftp_files,
-         );
-        
-        $form['ftp']['scan'] = array(
-            '#type' => 'button', 
-            '#value' => t('Detect new files'),
-        );
-        
-    }
-        
-    $settings = _user_import_settings_select(NULL, 'get saved');
-    
-    if ($settings) {
- 
-        $saved_settings = array(t('-- none --'));
-        foreach ($settings AS $settings_set) {
-            $saved_settings[$settings_set['import_id']] = $settings_set['name'];
-        }
-           
-        $form['import_template_select'] = array( 
-            '#type' => 'select',
-            '#title' => t('Saved Settings'),
-            '#description' => t('Select if you want to use a previously saved set of settings.'),
-            '#default_value' => variable_get('user_import_settings', 0),
-            '#options' => $saved_settings,
-        );
-        
-    } 
- 
-    $form['next'] = array(
-        '#type' => 'submit', 
-        '#value' => t('Next')
-    );    
-    
-    // Set form parameters so we can accept file uploads.
-    $form['#attributes'] = array('enctype' => 'multipart/form-data'); 
-
-    return $form;    
+  return $form;
 }
-function user_import_add_form_validate($form_id, $form_values) {
 
-    $file = _user_import_file(NULL, $form_values['file_ftp']);
+function user_import_add_form_validate($form, &$form_state) {
+
+    $file = _user_import_file(NULL, $form_state['values']['file_ftp']);
 
     // check file uploaded OK
     if (empty($file->filename)) form_set_error('file_upload', t('A file must be uploaded or selected from FTP updates.'));
-    
+
     // check file matches saved settings
-    
+
     return;
 }
-function user_import_add_form_submit($form_id, $form_values) {
 
-    $file = _user_import_file(NULL, $form_values['file_ftp']);
-    $form_values['filename'] = $file->filename;
-    $form_values['oldfilename'] = $file->filename;
-    $form_values['filepath'] = $file->filepath;
-    $form_values['setting'] = 'file set';
-    
+function user_import_add_form_submit($form, &$form_state) {
+
+    $file = _user_import_file(NULL, $form_state['values']['file_ftp']);
+    $form_state['values']['filename'] = $file->filename;
+    $form_state['values']['oldfilename'] = $file->filename;
+    $form_state['values']['filepath'] = $file->filepath;
+    $form_state['values']['setting'] = 'file set';
+
     // create import setting
-    $import = _user_import_settings_save($form_values, $messages = NULL);
-    if (!empty($form_values['import_template_select'])) $settings_template = check_plain($form_values['import_template_select']);
-    
-    drupal_goto('admin/user/user_import/add/' . $import['import_id'] . '/' . $settings_template);
-    
+    $import = _user_import_settings_save($form_state['values']);
+    if (!empty($form_state['values']['import_template_select'])) $settings_template = check_plain($form_state['values']['import_template_select']);
+
+    drupal_goto('admin/user/user_import/add/'. $import['import_id'] .'/'. $settings_template);
+
     return;
 }
 
-function user_import_edit_form($import_id, $template_id = NULL) {
-
+function user_import_edit_form($form_state, $import_id, $template_id = NULL) {
+    user_import_load_supported();
     $form = array();
     $import  = _user_import_settings_select($import_id);
     $import['template_id'] = $template_id;
-   
+
     // add setting template values
     if ($import['setting'] == 'file set') $import = _user_import_initialise_import($import);
-    
+
     $form['import_id'] = array(
-        '#type' => 'value', 
+        '#type' => 'value',
         '#value' => $import_id,
     );
-    
+
     $form['setting'] = array(
-        '#type' => 'value', 
+        '#type' => 'value',
         '#value' => $import['setting'],
     );
- 
+
+    $form['return_path'] = array(
+        '#type' => 'value',
+        '#default_value' => 'admin/user/user_import',
+    );
+
+    $form['og_id'] = array(
+        '#type' => 'value',
+        '#default_value' => 0,
+    );
+
+    // don't use hook because these need to be added in this order;
     user_import_edit_file_fields($form, $import);
-    user_import_edit_remove_fields($form, $import);
-    user_import_edit_settings_fields($form, $import);
-    user_import_edit_match_fields($form, $import);
-    user_import_edit_subscribed_fields($form, $import);
-    user_import_edit_template_fields($form, $import);
+    user_import_form_field_match($form, $import);
+
+    $collapsed = (empty($import['name'])) ? FALSE: TRUE;
+    $additional_fieldsets = module_invoke_all('user_import_form_fieldset', $import, $collapsed);
+    if (is_array($additional_fieldsets)) $form = $form + $additional_fieldsets;
 
     // don't show test option if import has started
     if ($import['setting'] != 'import' && $import['setting'] != 'imported') {
- 
+
         $form['test'] = array(
-            '#type' => 'submit', 
+            '#type' => 'submit',
             '#value' => t('Test'),
+            '#weight' => 100,
         );
     }
-    
+
     $form['import'] = array(
-        '#type' => 'submit', 
+        '#type' => 'submit',
         '#value' => t('Import'),
+        '#weight' => 100,
     );
-    
+
     $form['cancel'] = array(
-        '#type' => 'submit', 
+        '#type' => 'submit',
         '#value' => t('Cancel'),
-    ); 
+        '#weight' => 100,
+    );
 
-    return $form;  
+    return $form;
 }
-function user_import_edit_form_validate($form_id, $form_values) {
 
-    switch ($form_values[op]) {
-        
+function user_import_edit_form_validate($form, &$form_state) {
+
+    switch ($form_state['values']['op']) {
+
         case t('Remove file'):
 
-            _user_import_settings_deletion($form_values['import_id']);
-            _user_import_file_deletion($form_values['filepath'], $form_values['filename'], $form_values['oldfilename']);
-            drupal_goto ('admin/user/user_import/add');
-            
+            _user_import_settings_deletion($form_state['values']['import_id']);
+            _user_import_file_deletion($form_state['values']['filepath'], $form_state['values']['filename'], $form_state['values']['oldfilename']);
+            drupal_goto('admin/user/user_import/add');
+
             break;
-            
+
         case t('Cancel'):
 
             // if import was being added - delete file
-            if ($form_values['setting'] == 'file set') {
-                _user_import_settings_deletion($form_values['import_id']);
-                _user_import_file_deletion($form_values['filepath'], $form_values['filename'], $form_values['oldfilename']);
+            if ($form_state['values']['setting'] == 'file set') {
+                _user_import_settings_deletion($form_state['values']['import_id']);
+                _user_import_file_deletion($form_state['values']['filepath'], $form_state['values']['filename'], $form_state['values']['oldfilename']);
             }
-            drupal_goto ('admin/user/user_import');
+            drupal_goto('admin/user/user_import');
             break;
-            
+
         // save settings
         case t('Save As New'):
-        
-            $template_name = trim($form_values['new_name']);
-        
+
+            $template_name = trim($form_state['values']['new_name']);
+
         case t('Save'):
-        
-            if (empty($template_name)) $template_name = trim($form_values['name']);
-            
+
+            if (empty($template_name)) $template_name = trim($form_state['values']['name']);
+
             if (empty($template_name)) form_set_error('name', t('A name needs to be set to save this settings template.'));
-            
+
             // check settings template name is unique
             $unique_name = db_result(db_query("SELECT COUNT(import_id) FROM {user_import} WHERE name = '%s'", $template_name));
-            
+
             if (!empty($unique_name)) form_set_error('name', t("'!name' is already in use by another settings template.", array('!name' => $template_name)));
-               
+
         case t('Test'):
         case t('Import'):
+        default:
 
             $fields = array();
-           
-            while (list ($row, $values) = each ($form_values['field_match'])) {
-        
+
+            while (list ($row, $values) = each ($form_state['values']['field_match'])) {
+
                 // check each field is unique
-                if ($values['field_match'] != '0' && in_array($values['field_match'], $fields)) {
-                    
+                if ($values['field_match'] != '0' && $values['field_match'] != '-------------' && in_array($values['field_match'], $fields)) {
+
                     form_set_error('field_match', t('Database fields can only be matched to one column of the csv file.'));
                 }
-                
+
                 $fields[$values['field_match']] = $values['field_match'];
-                
+
                 // check email address has been selected
-                if ($values['field_match'] == 'email') $email = TRUE;
+                if ($values['field_match'] == 'user-email') $email = TRUE;
             }
-           
             if (!$email) form_set_error('email', t('One column of the csv file must be set as the email address.'));
-        
-            if ($form_values['name']) {
-               $form_values['name'] = rtrim($form_values['name']);
-               
-               if (drupal_strlen($form_values['name']) < 1 || drupal_strlen($form_values['name']) > 25) {
+
+            if ($form_state['values']['name']) {
+              $form_state['values']['name'] = rtrim($form_state['values']['name']);
+
+              if (drupal_strlen($form_state['values']['name']) < 1 || drupal_strlen($form_state['values']['name']) > 25) {
                 form_set_error('name', t('Name of saved settings must be 25 characters or less.'));
-               }
+              }
             }
             break;
     }
-    
+
     return;
 }
-function user_import_edit_form_submit($form_id, $form_values) {
-    
-    switch ($form_values[op]) {
-    
+
+function user_import_edit_form_submit($form, &$form_state) {
+
+    switch ($form_state['values']['op']) {
+
         // save settings
         case t('Save As New'):
-            $form_values['name'] = $form_values['new_name'];
-            
+            $form_state['values']['name'] = $form_state['values']['new_name'];
+
         case t('Save'):
-            
-            // save settings for inport
-            _user_import_settings_save($form_values);
-            
+
+            // save settings for import
+            _user_import_settings_save($form_state['values']);
+
             // save settings for template
-            $import_return = 'admin/user/user_import/add/' . $form_values['import_id'];
-            $form_values['setting'] = 'template';
-            unset($form_values['import_id']);
-            _user_import_initialise_import($form_values);
-            
+            $import_return = 'admin/user/user_import/add/'. $form_state['values']['import_id'];
+            $form_state['values']['setting'] = 'template';
+            unset($form_state['values']['import_id']);
+            _user_import_initialise_import($form_state['values']);
+
             // reload settings page
-            drupal_set_message (t("'%name' was saved as a settings template.", array('%name' => $form_values['name'])));
-            drupal_goto($import_return);
-            break;
+            drupal_set_message(t("'%name' was saved as a settings template.", array('%name' => $form_state['values']['name'])));
+            return $import_return;
 
         case t('Update'):
-          
+
             // get template id
-            $template_id = db_result(db_query("SELECT import_id from {user_import} where setting = 'template' AND name= '%s' LIMIT 1", $form_values['name']));
-            
+            $template_id = db_result(db_query_range("SELECT import_id from {user_import} where setting = 'template' AND name= '%s'", $form_state['values']['name'], 0, 1));
+
             // save settings for import
-            _user_import_settings_save($form_values);
-            
+            _user_import_settings_save($form_state['values']);
+
             // save settings for template
-            $import_return = 'admin/user/user_import/add' . $form_values['import_id'];
-            $form_values['setting'] = 'template';
-            $form_values['import_id'] = $template_id;
-            _user_import_initialise_import($form_values);
-            
+            $import_return = 'admin/user/user_import/add'. $form_state['values']['import_id'];
+            $form_state['values']['setting'] = 'template';
+            $form_state['values']['import_id'] = $template_id;
+            _user_import_initialise_import($form_state['values']);
+
             // reload settings page
-            drupal_set_message (t("'%name' settings template was updated.", array('%name' => $form_values['name'])));
-            drupal_goto($import_return);
-            break; 
-            
+            drupal_set_message(t("'%name' settings template was updated.", array('%name' => $form_state['values']['name'])));
+            return $import_return;
+
         case t('Test'):
-            if ($form_values['setting'] == 'file set') $filepath = file_move($form_values['filepath'], file_directory_path() . '/' . $form_values['filename']);
-            $form_values['setting'] = 'test';
+            if ($form_state['values']['setting'] == 'file set') $filepath = file_move($form_state['values']['filepath'], file_directory_path() .'/'. $form_state['values']['filename']);
+            $form_state['values']['setting'] = 'test';
             drupal_set_message(t('Tested'));
             break;
-            
+
         case t('Import'):
-            if ($form_values['setting'] == 'file set') $filepath = file_move($form_values['filepath'], file_directory_path() . '/' . $form_values['filename']);
-            $form_values['setting'] = 'import';
-            drupal_set_message (t('Imported'));
-            break;            
-    }  
-    
-    $form_values = _user_import_settings_save($form_values, 'display message');
-
-    $form_values['save']['update'] = NULL;
-    $form_values['import_template_id'] = NULL;
-    $form_values['save']['name'] = NULL;
-    _user_import_process($form_values);
-    drupal_goto ('admin/user/user_import');
+        default:
+            if ($form_state['values']['setting'] == 'file set') $filepath = file_move($form_state['values']['filepath'], file_directory_path() .'/'. $form_state['values']['filename']);
+            if (!empty($form_state['values']['og_id'])) $form_state['values']['groups'][$form_state['values']['og_id']] = $form_state['values']['og_id'];
+
+            $form_state['values']['setting'] = 'import';
+            drupal_set_message(t('Imported'));
+            break;
+    }
+
+    $form_state['values'] = _user_import_settings_save($form_state['values']);
+
+    $form_state['values']['save']['update'] = NULL;
+    $form_state['values']['import_template_id'] = NULL;
+    $form_state['values']['save']['name'] = NULL;
+    _user_import_process($form_state['values']);
+    return $form_state['values']['return_path'];
+
+}
+
+function user_import_preconfigured($template_id = NULL, $import_id = NULL, $og_id = NULL) {
+
+    if (empty($template_id)) drupal_access_denied();
+    $exists = db_result(db_query("SELECT COUNT(import_id) FROM {user_import} WHERE import_id = %d AND setting = 'template'", $template_id));
+    if (empty($exists)) drupal_access_denied();
+
+    $form = array();
+
+    $form['template_id'] = array(
+      '#type' => 'value',
+      '#value' => $template_id,
+    );
+
+    $form['og_id'] = array(
+      '#type' => 'value',
+      '#value' => $og_id,
+    );
+
+    user_import_add_file_form($form);
+
+    $form['next'] = array(
+        '#type' => 'submit',
+        '#value' => t('Import Users')
+    );
+
+    // Set form parameters so we can accept file uploads.
+    $form['#attributes'] = array('enctype' => 'multipart/form-data');
+
+    if (!empty($import_id)) {
+
+      // check access
+      $exists = db_result(db_query("SELECT COUNT(import_id) FROM {user_import} WHERE import_id = %d", $import_id));
+
+      if (!empty($exists)) {
+
+        $form['status'] = array(
+            '#value' => '<div class="user-import-report">
+                          <h3>'. t('Import Report') .'</h3>'.
+                          theme('user_import_limited_list', $import_id, $template_id) .
+                          '</div>',
+        );
+      }
+    }
+
+    return $form;
+}
+
+function user_import_preconfigured_validate($form, &$form_state) {
+
+  // check file uploaded OK
+  $file = _user_import_file();
+  if (empty($file->filename)) form_set_error('file_upload', t('A valid file must be selected.'));
+}
+
+function user_import_preconfigured_submit($form, &$form_state) {
+
+  $file = _user_import_file();
+
+  $form_state['values']['filename'] = $file->filename;
+  $form_state['values']['oldfilename'] = $file->filename;
+  $form_state['values']['filepath'] = $file->filepath;
+  $form_state['values']['setting'] = 'file set';
+
+  $import = _user_import_settings_save($form_state['values']);
+
+  // submit the form using these values
+  $form_id = 'user_import_edit_form';
+  $field_values = array('return_path' => 'user_import/'. $form_state['values']['template_id'] .'/'. $import['import_id'] .'/'. $form_state['values']['og_id']);
+  $field_values['og_id'] = $form_state['values']['og_id'];
+  $errors = drupal_execute($form_id, $field_values, $import['import_id'], $form_state['values']['template_id']);
+  return;
+}
+
+function user_import_add_file_form(&$form, $ftp_files = NULL) {
+
+    $form['browser'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Browser Upload'),
+        '#collapsible' => TRUE,
+        '#description' => t("Upload a CSV file."),
+    );
+
+    if (function_exists('file_upload_max_size')) $file_size = t('Maximum file size: !size MB.', array('!size' => file_upload_max_size()));
+
+    $form['browser']['file_upload'] = array(
+        '#type' => 'file',
+        '#title' => t('CSV File'),
+        '#size' => 40,
+        '#description' => t('Select the CSV file to be imported.') . $file_size,
+    );
+
+    if (!empty($ftp_files)) {
+
+      $form['ftp'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('FTP Upload'),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+          '#description' => t("Any files uploaded to the 'user_import' directory using FTP can be selected for import here. Useful if the import file is too large for upload via the browser."),
+      );
+
+      $form['ftp']['file_ftp'] = array(
+            '#type' => 'radios',
+            '#title' => t('Files'),
+            '#default_value' => 0,
+            '#options' => $ftp_files,
+      );
+
+      $form['ftp']['scan'] = array(
+          '#type' => 'button',
+          '#value' => t('Check for new files'),
+      );
+
+    }
 
     return;
 }
 
 
-// - - - - - - - -  PAGES - - - - - - - - 
+// - - - - - - - -  PAGES - - - - - - - -
 
 function user_import_preferences($import_id = NULL, $template_id = NULL) {
+  if (empty($import_id)) {
+    $output .= drupal_get_form('user_import_add_form');
+  }
+  else {
+    $output .= drupal_get_form('user_import_edit_form', $import_id, $template_id);
+  }
 
-    if (empty($import_id)) {
-        $output .= drupal_get_form('user_import_add_form');
-    } else {
-        $output .= drupal_get_form('user_import_edit_form', $import_id, $template_id);
-    }
-    
-    return $output;
+  return $output;
 }
 
 function user_import_list($action = NULL, $import_id = NULL) {
-  
+
     // clear incomplete imports
     _user_import_incomplete_deletion();
-    
+
     if (!empty($import_id) && is_numeric($import_id)) {
-		
-		$import = _user_import_settings_select($import_id);
-		$output = theme('user_import_errors', $import);
-		
-    } else {
-    	
-    	$output =  theme_user_import_list();
+
+      $pager_id = 1;
+      $max = 25;
+      $import = _user_import_settings_select($import_id);
+
+      $total = db_result(db_query("SELECT count(data) FROM {user_import_errors} WHERE import_id = %d", $import['import_id']));
+      $results = pager_query("SELECT * FROM {user_import_errors} WHERE import_id = %d", $max, $pager_id, NULL, array($import['import_id']));
+
+      while ($line = db_fetch_array($results)) {
+          $line['data'] = unserialize($line['data']);
+          $line['errors'] = unserialize($line['errors']);
+          $file_lines[] = $line;
+      }
+
+      $output = theme('user_import_errors_display', $import, $file_lines, $total);
+      $output .= theme('pager', NULL, $max, $pager_id);
+
+    }
+    else {
+
+      $output =  theme_user_import_list();
     }
 
-    
-    
-    return $output;    
+
+
+    return $output;
 }
 
 function user_import_continue($import_id = NULL) {
+  if (!empty($import_id) && is_numeric($import_id)) {
+    $import = _user_import_settings_select($import_id);
+    _user_import_process($import);
+  }
 
-    if (!empty($import_id) && is_numeric($import_id)) {
-        
-		$import = _user_import_settings_select($import_id);
-		_user_import_process($import);
-    }
-    
-    drupal_goto('admin/user/user_import');
+  drupal_goto('admin/user/user_import');
 }
 
 function user_import_import($import_id = NULL) {
 
     if (!empty($import_id) && is_numeric($import_id)) {
-        
-		$import = _user_import_settings_select($import_id);
-		_user_import_initialise_import($import);
+
+    $import = _user_import_settings_select($import_id);
+    _user_import_initialise_import($import);
     }
-    
+
     drupal_goto('admin/user/user_import');
 }
 
-function user_import_errors($import_id = NULL) {
+function user_import_errors_display($import_id = NULL) {
 
-    if (empty($import_id) || !is_numeric($import_id)) drupal_goto('admin/user/user_import');
-        
-    $import = _user_import_settings_select($import_id);
-    $output = theme('user_import_errors', $import);
-    return $output;
+  if (empty($import_id) || !is_numeric($import_id)) drupal_goto('admin/user/user_import');
+
+  $import = _user_import_settings_select($import_id);
+  $output = theme('user_import_errors_display', $import);
+  return $output;
 }
 
-function user_import_delete($import_id = NULL) {
+function user_import_limited_errors($import_id = NULL, $template_id = NULL) {
+
+  if (empty($import_id) || !is_numeric($import_id)) drupal_goto('user_import/'. $template_id);
+
+  $pager_id = 1;
+  $max = 25;
+  $import = _user_import_settings_select($import_id);
+
+  $total = db_result(db_query("SELECT count(data) FROM {user_import_errors} WHERE import_id = %d", $import['import_id']));
+
+  if (empty($total))  {
+
+    $output .= theme('There were no import errors');
+
+  }
+  else {
+
+    $results = pager_query("SELECT * FROM {user_import_errors} WHERE import_id = %d", $max, $pager_id, NULL, array($import['import_id']));
+
+    while ($line = db_fetch_array($results)) {
+
+      $line['data'] = unserialize($line['data']);
+      $line['errors'] = unserialize($line['errors']);
+      $file_lines[] = $line;
+    }
+
+    $output .= theme('user_import_errors_display', $import, $file_lines, $total);
+    $output .= theme('pager', NULL, $max, $pager_id);
+  }
+
+  $output .= l(t('Return'), "user_import/$template_id/$import_id");
+
+  return $output;
+}
+
+
+// errors for user being imported
+function user_import_errors($error = FALSE, $clear = FALSE) {
+
+  static $errors = array();
+  if ($clear) $errors = array();
+  if ($error) $errors[] = $error;
+  return $errors;
+}
+
+function user_import_limited_delete($import_id = NULL, $template_id = NULL) {
+
+  user_import_delete($import_id, "user_import/$template_id");
+}
+
+function user_import_delete($import_id = NULL, $return_path = 'admin/user/user_import') {
+
+    if (empty($import_id) || !is_numeric($import_id)) drupal_goto($return_path);
 
-    if (empty($import_id) || !is_numeric($import_id)) drupal_goto('admin/user/user_import');
-        
     $import = _user_import_settings_select($import_id);
-    
+
     _user_import_settings_deletion($import_id);
     _user_import_file_deletion($import['filepath'], $import['filename'], $import['oldfilename']);
-    drupal_goto('admin/user/user_import');
+    drupal_goto($return_path);
     return;
 }
 
 
-// - - - - - - - -  THEMES - - - - - - - - 
+// - - - - - - - -  THEMES - - - - - - - -
+function user_import_theme() {
+  return array(
+    'user_import_list' => array(
+    ),
+    'user_import_limited_list' => array(
+      'arguments' => array('import_id' => NULL, 'template_id' => NULL)
+    ),
+    'user_import_edit_form' => array(
+      'arguments' => array('form' => NULL)
+    ),
+    'user_import_errors_display' => array(
+      'arguments' => array('settings' => NULL, 'data' => NULL, 'total' => NULL)
+    ),
+    'user_import_username_errors' => array(
+      'arguments' => array('errors' => NULL)
+    )
+  );
+}
 
 function theme_user_import_list() {
 
-    $imports = _user_import_settings_select();
-    
-    if (!$imports) return ' ';
+  $imports = _user_import_settings_select();
 
-    foreach ($imports as $import) {
+  if (!$imports) return ' ';
 
-        // header labels
-        $import_label = ($import['setting'] == 'tested' || $import['setting'] == 'test') ? t('importable') : t('imported');
-        $header = array(t('file'), t('started'), t('processed'), $import_label, t('errors'), t('status'));
-                    
-        // info row
-        $errors = db_result(db_query("SELECT COUNT(import_id) FROM {user_import_errors} WHERE import_id = %d", $import['import_id']));         
-        $errors_link = ($errors == 0) ? '0': l($errors, 'admin/user/user_import/errors/' . $import['import_id']);           
-        
-        $rows[0] = array(
-            check_plain($import['oldfilename']),
-            format_date($import['started'], 'small'),
-            array("data" => $import['processed'], "align" => 'center'),
-            array("data" => $import['valid'], "align" => 'center'),
-            array("data" => $errors_link, "align" => 'center'),
-            $import['setting'],
-        );
-        
-        $output .= theme('table', $header, $rows);
-        
-        // action buttons
-        $settings_link = l(t('Settings'), 'admin/user/user_import/add/' . $import['import_id']);
-        $delete_link = l(t('Delete'), 'admin/user/user_import/delete/' . $import['import_id']);
-        $continue_link = l(t('Continue Processing'), 'admin/user/user_import/continue/' . $import['import_id']);
-        $import_link = l(t('Import'), 'admin/user/user_import/import/' . $import['import_id']);
-        
-        $output .= $settings_link  . ' | ';   
-        $output .= $delete_link;   
-        if ($import['setting'] == 'tested' || $import['setting'] == 'test') $output .= ' | ' . $import_link;
-        if ($import['setting'] == 'test' || $import['setting']  == 'import') $output .= ' | ' . $continue_link;
-    } 
-    
-    return $output;
+  foreach ($imports as $import) {
+
+      // header labels
+      $import_label = ($import['setting'] == 'tested' || $import['setting'] == 'test') ? t('importable') : t('imported');
+      $header = array(t('file'), t('started'), t('processed'), $import_label, t('errors'), t('status'));
+
+      // info row
+      $errors = db_result(db_query("SELECT COUNT(import_id) FROM {user_import_errors} WHERE import_id = %d", $import['import_id']));
+      $errors_link = ($errors == 0) ? '0': l($errors, 'admin/user/user_import/errors/'. $import['import_id']);
+
+      $rows[0] = array(
+          check_plain($import['oldfilename']),
+          format_date($import['started'], 'small'),
+          array("data" => $import['processed'], "align" => 'center'),
+          array("data" => $import['valid'], "align" => 'center'),
+          array("data" => $errors_link, "align" => 'center'),
+          $import['setting'],
+      );
+
+      $output .= theme('table', $header, $rows);
+
+      // action buttons
+      $settings_link = l(t('Settings'), 'admin/user/user_import/add/'. $import['import_id']);
+      $delete_link = l(t('Delete'), 'admin/user/user_import/delete/'. $import['import_id']);
+      $continue_link = l(t('Continue Processing'), 'admin/user/user_import/continue/'. $import['import_id']);
+      $import_link = l(t('Import'), 'admin/user/user_import/import/'. $import['import_id']);
+
+      $output .= $settings_link  .' | ';
+      $output .= $delete_link;
+      if ($import['setting'] == 'tested' || $import['setting'] == 'test') $output .= ' | '. $import_link;
+      if ($import['setting'] == 'test' || $import['setting']  == 'import') $output .= ' | '. $continue_link;
+  }
+
+  return $output;
+}
+
+function theme_user_import_limited_list($import_id, $template_id = NULL) {
+
+  $import = _user_import_settings_select($import_id);
+
+  if (!$import) return ' ';
+
+  // header labels
+  $import_label = ($import['setting'] == 'tested' || $import['setting'] == 'test') ? t('importable') : t('imported');
+  $header = array(t('file'), t('started'), t('processed'), $import_label, t('errors'), t('status'));
+
+  // info row
+  $errors = db_result(db_query("SELECT COUNT(import_id) FROM {user_import_errors} WHERE import_id = %d", $import['import_id']));
+  $errors_link = ($errors == 0) ? '0': l($errors, 'user_import/errors/'. $import_id .'/'. $template_id);
+
+  $rows[0] = array(
+      check_plain($import['oldfilename']),
+      format_date($import['started'], 'small'),
+      array("data" => $import['processed'], "align" => 'center'),
+      array("data" => $import['valid'], "align" => 'center'),
+      array("data" => $errors_link, "align" => 'center'),
+      $import['setting'],
+  );
+
+  $output .= theme('table', $header, $rows);
+
+  // action buttons
+  $delete_link = l(t('Remove Info'), 'user_import/delete/'. $import_id .'/'. $template_id);
+  $continue_link = l(t('Continue Processing'), 'user_import/continue/'. $import_id .'/'. $template_id);
+  $import_link = l(t('Import'), 'user_import/import/'. $import_id .'/'. $template_id);
+
+  $output .= $delete_link;
+  if ($import['setting'] == 'tested' || $import['setting'] == 'test') $output .= ' | '. $import_link;
+  if ($import['setting'] == 'test' || $import['setting']  == 'import') $output .= ' | '. $continue_link;
+
+
+  return $output;
 }
 
 function theme_user_import_edit_form($form) {
-    
+
     $header = array(t('csv column'), t('Drupal fields'), t('username'), t('abbreviate'));
-    
+
     foreach (element_children($form['field_match']) as $key) {
 
         $rows[] = array(
@@ -699,7 +945,7 @@ function theme_user_import_edit_form($fo
             drupal_render($form['field_match'][$key]['abbreviate']),
         );
     }
-    
+
     $form['field_match']['#value'] = theme('table', $header, $rows);
 
     $output .= drupal_render($form['remove']);
@@ -709,630 +955,233 @@ function theme_user_import_edit_form($fo
     return $output;
 }
 
-function theme_user_import_errors($import) {
-
-    $errors = 0;
-    
-    $output .= '<h3>' . t('Import Errors') . '</h3>';
-    $output .= '<p>' . t('<strong>CSV File:</strong> %file', array('%file' => $import['oldfilename'])) . '<br />';
-    
-    // get profile fields
-    $profile_fields = _user_import_profile('fid', 'title');
-    
-    // add email address options
-    $profile_fields['email'] = t('Email Address');
-    asort($profile_fields);
+function theme_user_import_errors_display($settings, $data, $total) {
 
-    foreach ($import['field_match'] as $settings) {     
-        if ($settings['field_match'] != '0') $header[] = $profile_fields[$settings['field_match']];
+  $error_count = 0;
+  $field_match = _user_import_unconcatenate_field_match($settings['field_match']);
+  $header[0] = t('Email Address');
+
+  foreach ($data as $data_row) {
+    $row = NULL;
+
+    foreach ($data_row['data'] as $type => $fields) {
+      if (!empty($fields)) {
+        foreach ($fields as $field_id => $field_data) {
+          foreach ($field_match as $column_info) {
+            if ($column_info['type'] ==  $type && $column_info['field_id'] == $field_id) {
+              if (!empty($column_info['username'])) {
+                $header[$column_info['username']] = t('Name %sort', array('%sort' => $column_info['username']));
+                $row[$column_info['username']] = array("data" => $field_data[0], "align" => "left");
+              }
+              if ($column_info['field_id'] == 'email') {
+                $row[0] = array("data" => $field_data[0], "align" => "left");
+              }
+            }
+          }
+        }
+      }
     }
 
-    $results = db_query("SELECT * FROM {user_import_errors} WHERE import_id = %d", $import['import_id']);
-    while ($line = db_fetch_array($results)) {
-        $line['data'] = unserialize($line['data']);
-        $file_lines[] = $line;
-    }
+    ksort($row);
 
-    foreach ($file_lines as $file_line) {
-        
-        $errors++;
-        $row = NULL;
-        foreach ($file_line['data'] as $file_cell) {
-            $row[] = array("data" => drupal_substr($file_cell, 0, 40), "align" => "left");
-        }
-        
-        $row[] = $file_line['error'];
-        $rows[] = $row;
+    if ($data_row['errors'] !== false ) {
+      $row[] = 'User exists and "Update account" is not enabled.';
     }
+    $rows[] = $row;
+  }
 
-    $output .= t('<strong>Errors:</strong> !errors', array('!errors' => $errors)) . '</p>';
-    $header[] = t('error');
-    
-    $output .= theme('table', $header, $rows);    
-    return $output;
+  $output .= '<p>'. t('<strong>CSV File:</strong> %file', array('%file' => $settings['oldfilename'])) .'<br />';
+  $output .= t('<strong>Errors:</strong> !total', array('!total' => $total)) .'</p>';
+
+  $header['errors'] = t('Errors');
+  $output .= theme('table', $header, $rows);
+  return $output;
 }
 
 function theme_user_import_username_errors($errors) {
-    
+
     if (empty($errors)) {
-        $output = '<p><strong>' . t('All usernames are OK.') . '</strong></p>';
-    } else {
+        $output = '<p><strong>'. t('All usernames are OK.') .'</strong></p>';
+    }
+    else {
         $header = array(t('User ID'), t('Email'), t('Username'), t('Error'));
         $output = theme('table', $header, $errors);
     }
-    
+
     return $output;
 }
 
-// - - - - - - - -  MISC - - - - - - - - 
+// - - - - - - - -  MISC - - - - - - - -
 
 function user_import_edit_file_fields(&$form, $import) {
-    
-    $form['filename'] = array(
-        '#type' => 'value',
-        '#value' => $import['filename'],
-    );
-    
-    $form['oldfilename'] = array(
-        '#type' => 'value',
-        '#value' => $import['oldfilename'],
-    );
-    
-    $form['filepath'] = array(
-        '#type' => 'value',
-        '#value' => $import['filepath'],
-    );
-    
-    return;
-}
-
-function user_import_edit_remove_fields(&$form, $import) {
-        
-    $form['remove'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Use Different CSV File'),
-        '#description' => t('Remove file to use a different file. All settings on this page will be deleted.'),
-        '#collapsible' => TRUE,
-        '#collapsed' => TRUE, 
-    );
-    
-    $form['remove']['file'] = array(
-        '#type' => 'item', 
-        '#title' => t('Uploaded file'),
-        '#value' => $import['filename']
-    );
- 
-    $form['remove']['submit'] = array(
-        '#type' => 'submit', 
-        '#value' => t('Remove file')
-    );
-
-    return;
-}
-
-function user_import_edit_settings_fields(&$form, $import) { 
-        
-    $collapsed = (empty($import['name'])) ? FALSE: TRUE;
-    $profile_string = user_import_profile_string();
-
-    $form['optional'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Options'),
-        '#collapsible' => TRUE,
-        '#collapsed' => $collapsed, 
-    );
-    
-    $form['optional']['first_line_skip'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Ignore First Line'),
-        '#default_value' => $import['first_line_skip'],
-        '#description' => t('If the first line is the names of the data columns, set to ignore first line.'),
-    );
-    
-    $form['optional']['contact'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Contact'),
-        '#default_value' => $import['contact'],
-        '#description' => t("Set each user's personal contact form to 'allowed'."),
-    );
-    
-    $form['optional']['send_email'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Send Email'),
-        '#default_value' => $import['send_email'],
-        '#description' => t('Send email to users when their account is created.'),
-    );
-    
-    $form['optional']['username_space'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Username Space'),
-        '#default_value' => $import['username_space'],
-        '#description' => t("Include spaces in usernames, e.g. 'John' + 'Smith' => 'John Smith'."),
-    );
-    
-    $form['optional']['activate'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Activate Accounts'),
-        '#default_value' => $import['options']['activate'],
-        '#description' => t("User accounts will not be visible to other users until their owner logs in. Select this option to make all imported user accounts visible."),
-    );
-  
-    
-    $roles_data = user_roles();
-    // remove 'anonymous user' option
-    while (list ($rid, $role_name) = each ($roles_data)) {
-        if ($role_name != 'anonymous user' && $role_name != 'authenticated user') $roles[$rid] = $role_name;
-    }
-    
-    // roles selected
-    if ( !empty($import['roles']) ) {
-        foreach ($import['roles'] as $rid) {
-            if ($rid != 0) $roles_selected[] = $rid;
-        }
-    }
-    
-    if ( empty($roles_selected) ) $roles_selected[] = 2; 
-
-    $form['role_selection'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Role Assign'),
-        '#description' => t("Select which role(s) imported users should be assigned. The role 'authenticated user' is assigned automatically."),
-        '#collapsible' => TRUE,
-        '#collapsed' => $collapsed,
-    );
-    
-    $form['role_selection']['roles'] = array(
-        '#type' => 'checkboxes',
-        '#options' => $roles,
-        '#default_value' => $roles_selected,
-    );
-    
-    if (module_exists('og')) {
-    
-        $groups = user_import_get_groups();
-        
-        $groups_description = empty($groups) ? t('No Groups have been defined.') : t('Select which group(s) imported users should be assigned.');
-        
-        $form['group_assign'] = array(
-            '#type' => 'fieldset',
-            '#title' => t('Group Assign'),
-            '#description' => $groups_description,
-            '#collapsible' => TRUE,
-            '#collapsed' => $collapsed, 
-        );
-        
-        if (!empty($groups)) {
-
-          $form['group_assign']['groups'] = array(
-            '#type' => 'checkboxes',
-            '#title' => t('Groups'),
-            '#options' => $groups,
-            '#default_value' => $import['options']['groups'],
-          );
-          
-          $form['group_assign']['existing'] = array(
-              '#type' => 'fieldset',
-              '#title' => t('Existing Users'),
-              '#description' => t('Add to selected groups users who already have an account. Optionaly send them an email.'),
-              '#collapsible' => TRUE,
-              '#collapsed' => TRUE, 
-          );
-          
-           $form['group_assign']['existing']['existing_og_subscribe'] = array(
-                '#type' => 'radios',
-                '#title' => t('Subscribe'),
-                '#default_value' => $import['options']['existing_og_subscribe'],
-                '#options' => array(t('No'), t('Yes')),
-           ); 
-           
-          $form['group_assign']['existing']['existing_og_subject'] = array(
-            '#type' => 'textfield',
-            '#title' => t('Message Subject'),
-            '#default_value' => $import['options']['existing_og_subject'],
-            '#description' => t('Customize the subject of the email sent to existing users being added to groups.') .' '. t('Available variables are:') .' !username, !site, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url' . $profile_string . '.',
-          );
-          
-          $form['group_assign']['existing']['existing_og_markup'] = array(
-            '#type' => 'radios',
-            '#title' => t('Email Format'),
-            '#default_value' => empty($import['options']['existing_og_markup']) ? 0 : $import['options']['existing_og_markup'],
-            '#options' => array(t('Plain Text'), t('HTML')),
-          );
-           
-          $form['group_assign']['existing']['existing_og_message'] = array(
-            '#type' => 'textarea',
-            '#title' => t('Email Body'),
-            '#default_value' => $import['options']['existing_og_message'],
-            '#description' => t('Message to send existing users being added to groups. Users who are already in a group will not be sent a message.') .' '. t('Available variables are:') .' !username, !site, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url' . $profile_string . '.',
-          );
-          
-          $form['group_assign']['existing']['existing_og_css'] = array(
-            '#type' => 'textarea',
-            '#title' => t('Email CSS'),
-            '#default_value' => $import['options']['existing_og_css'],
-            '#description' => t('Use if sending HTML formated email.'),
-          );
-        
-        }
-    
-    }
-    
-    $form['email_message'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Email Message'),
-        '#description' => t('Welcome message to be sent to imported users. Leave blank to use the default !message.<br /><strong>Warning</strong>: if you copy and paste directly from Word some characters may get garbled.', array('!message' => l('message', 'admin/user/settings'))),
-        '#collapsible' => TRUE,
-        '#collapsed' => $collapsed,
-    );
+  $form['filename'] = array(
+    '#type' => 'value',
+    '#value' => $import['filename'],
+  );
+
+  $form['oldfilename'] = array(
+    '#type' => 'value',
+    '#value' => $import['oldfilename'],
+  );
+
+  $form['filepath'] = array(
+    '#type' => 'value',
+    '#value' => $import['filepath'],
+  );
 
-    $form['email_message']['subject'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Message Subject'),
-      '#default_value' => $import['options']['subject'],
-      '#description' => t('Customize the subject of the welcome e-mail, which is sent to imported members.') .' '. t('Available variables are:') .' !username, !site, !password, !uri, !uri_brief, !mailto, !date, !login_uri, !edit_uri, !login_url' . $profile_string . '.',
-    ); 
-    
-    $form['email_message']['message'] = array(
-      '#type' => 'textarea',
-      '#title' => t('Message'),
-      '#default_value' => $import['options']['message'],
-      '#description' => t('Customize the body of the welcome e-mail, which is sent to imported members.') .' '. t('Available variables are:') .' !username, !site, !password, !uri, !uri_brief, !mailto, !login_uri, !edit_uri, !login_url' . $profile_string . '.',
-    ); 
-    
-    $form['email_message']['message_format'] = array(
-      '#type' => 'radios',
-      '#title' => t('Email Format'),
-      '#default_value' => empty($import['options']['message_format']) ? 0 : $import['options']['message_format'],
-      '#options' => array(t('Plain Text'), t('HTML')),
-    );
-    
-    $form['email_message']['message_css'] = array(
-      '#type' => 'textarea',
-      '#title' => t('CSS'),
-      '#default_value' => $import['options']['message_css'],
-      '#description' => t('Use if sending HTML formated email.'),
-    );
-    
-    return;
+  return;
 }
 
-function user_import_edit_template_fields(&$form, $import) {
-    
-    // settings template update controls
-    if (empty($import['name'])) {
-    
-       // new settings template save controls
-        
-        $form['save'] = array(
-            '#type' => 'fieldset',
-            '#title' => t('Save Settings'),
-            '#description' => t('Save settings for re-use on other imports.'),
-            '#collapsible' => TRUE,
-            '#collapsed' => FALSE, 
-        );
-        
-         $form['save']['name'] = array(
-            '#type' => 'textfield',
-            '#title' => t('Settings Name'),
-            '#size' => 26,
-            '#maxlength' => 25,
-            '#description' => t('Name to identify these settings by.'),
-        );
-        
-        $form['save'][] = array(
-            '#type' => 'submit', 
-            '#value' => t('Save'),
-        );
- 
-    } 
-    else {
-        
-        $form['save'] = array(
-            '#type' => 'fieldset',
-            '#title' => t('Saved Settings'),
-            '#description' => t("If changes have neen made to the settings since they where last saved you can update the saved template, or save them as a new template."),
-            '#collapsible' => TRUE,
-            '#collapsed' => TRUE, 
-        );
-        
-        $form['save']['name'] = array(
-            '#type' => 'value', 
-            '#value' => $import['name']
-        );
+function user_import_form_field_match(&$form, $import) {
+  $collapsed = (empty($import['name'])) ? FALSE: TRUE;
+  $handle = _user_import_file_open($form['filepath']['#value'], $form['filename']['#value']);
+  $data_row = _user_import_file_row($form['filename']['#value'], $handle);
+
+  $fieldmatch_description = t("Match columns in CSV file to profile fields, leave as '----' if there is no match.");
+  $fieldmatch_description .= '<br /><strong>'. t('Username') .': </strong>'. t("The Username will be built from CSV columns in the order selected.");
+  $fieldmatch_description .= '<br /><strong>'. t('Abbreviate') .': </strong>'. t("Use the first letter of a field in uppercase for the Username, e.g. 'john' -> 'J'.");
+  $fieldmatch_description .= '<br />'. t("If no CSV fields are selected, the Username will be randomly generated.");
+
+  $form['field_match'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Field Match'),
+      '#description' => $fieldmatch_description,
+      '#weight' => -90,
+      '#collapsible' => TRUE,
+      '#collapsed' => $collapsed,
+      '#tree' => TRUE,
+  );
+
+  // add default and email address options
+  $user_fields[0] = '-------------';
+  $additional_user_fields = module_invoke_all('user_import_form_field_match');
 
-        $form['save']['update'] = array(
-            '#type' => 'fieldset',
-            '#title' => t('Update'),
-            '#description' => t("Update '%name' settings template", array('%name' => $import['name'])),
-        );
-        
-        $form['save']['update']['submit'] = array(
-            '#type' => 'submit', 
-            '#value' => t('Update'),
-        );
-            
-        $form['save']['new'] = array(
-            '#type' => 'fieldset',
-            '#title' => t('Create New'),
-            '#description' => t("Save as new settings template"),
-        );
-        
-         $form['save']['new']['new_name'] = array(
-            '#type' => 'textfield',
-            '#title' => t('Save As New'),
-            '#size' => 30,
-            '#maxlength' => 25,
-            '#description' => t('Name to identify these settings by.'),
-        );
-        
-        $form['save']['new'][] = array(
-            '#type' => 'submit', 
-            '#value' => t('Save As New'),
-        );
+  foreach ($additional_user_fields as $type => $type_options) {
 
+    foreach ($type_options as $field_id => $label) {
+      $user_fields["$type-$field_id"] = $label;
     }
-    
-    return;
-}
+  }
 
-function user_import_edit_match_fields(&$form, $import) {
+  asort($user_fields);
 
-    $collapsed = (empty($import['name'])) ? FALSE: TRUE;
+  $row = 0;
+  $sort = array(t('no'), 1, 2, 3, 4);
 
-    $handle = _user_import_file_open($form['filepath']['#value'], $form['filename']['#value']);
-    $data_row = _user_import_file_row($form['filename']['#value'], $handle);
+  if (empty($data_row)) return;
 
-    $profile_fields = _user_import_profile('fid', 'title');
+  foreach ($data_row as $data_cell) {
 
-    // add default and email address options
-    $profile_fields[0] = '-------------';
-    $profile_fields['email'] = t('Email Address') . '*';
-    $profile_fields['password'] = t('Password');
-    asort($profile_fields);  
-      
-    $row = 0;
-    $sort = array(t('no'), 1, 2, 3, 4);
-    
-    $fieldmatch_description = t("Match columns in CSV file to profile fields, leave as '----' if there is no match.");
-    $fieldmatch_description .= '<br /><strong>' . t('Username') . ': </strong>' . t("The Username will be built from CSV columns in the order selected.");
-    $fieldmatch_description .= '<br /><strong>' . t('Abbreviate') . ': </strong>' . t("Use the first letter of a field in uppercase for the Username, e.g. 'john' -> 'J'.");
-    $fieldmatch_description .= '<br />' . t("If no CSV fields are selected, the Username will be randomly generated.");
-    
-    $form['field_match'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Field Match'),
-        '#description' => $fieldmatch_description,
-        '#collapsible' => TRUE,
-        '#collapsed' => $collapsed, 
-        '#tree' => TRUE,
-    );
-    
-    if (empty($data_row)) return; 
-      
-    foreach ($data_row as $data_cell) {        
+      $form['field_match'][$row]= array(
+          '#tree' => TRUE,
+      );
 
-        $form['field_match'][$row]= array(
-            '#tree' => TRUE,
-        );
-   
-        $form['field_match'][$row]['csv'] = array( 
-            '#value' => check_plain(drupal_substr($data_cell, 0, 40)),
-        );
-    
-        $form['field_match'][$row]['field_match'] = array( 
-            '#type' => 'select',
-            '#default_value' => ($import['field_match'][$row]['field_match']) ? $import['field_match'][$row]['field_match'] : $profile_fields[0],
-            '#options' => $profile_fields,
-        );
+      $form['field_match'][$row]['csv'] = array(
+          '#value' => check_plain(drupal_substr($data_cell, 0, 40)),
+      );
 
-        $form['field_match'][$row]['username'] = array( 
-            '#type' => 'select',
-            '#default_value' => ($import['field_match'][$row]['username']) ? $import['field_match'][$row]['username'] : $sort[0],
-            '#options' => $sort,
-        );
-        
-        $form['field_match'][$row]['abbreviate'] = array( 
-            '#type' => 'checkbox',
-            '#default_value' => ($import['field_match'][$row]['abbreviate']) ? $import['field_match'][$row]['abbreviate'] : NULL,
-        );
-  
-        $row++;
-    }
-   
-    return;
-}
-  
-function _user_import_create_username($order, $data, $abbreviate, $username_space) {
-    
-    asort($order);
-    reset($order);
-
-    while (list ($file_column, $sequence) = each ($order)) {
-        
-        if (!empty($username) && !empty($username_space)) $username .= ' ';
-        $username .= ($abbreviate[$file_column] == 1) ? trim(drupal_strtoupper(chr(ord($data[$file_column])))) : trim($data[$file_column]);
-    }
-    
-    if (empty($username)) $username = _user_import_random_username();
-    
-    _user_import_sanitise_username($username);
-    
-    return $username;
-}
-      
-function _user_import_sanitise_username(&$username) {
+      $form['field_match'][$row]['field_match'] = array(
+          '#type' => 'select',
+          '#default_value' => ($import['field_match'][$row]['field_match']) ? $import['field_match'][$row]['field_match'] : $user_fields[0],
+          '#options' => $user_fields,
+      );
 
-    //
-    // conform to Drupal username rules
-    //
-    
-    static $sanitised = 0;
-    
-    if ($sanitised == 0) {
-  
-        // username cannot contain an illegal character
-        $username = preg_replace('/[^a-zA-Z0-9@ ]/', ' ', $username);
-        // username cannot contain multiple spaces in a row
-        $username = preg_replace('/[ ]+/', ' ', $username);   
-        
-        // username must be less than 56 characters
-        $username = substr($username, 0, 56);
-        
-        // username cannot begin or end with a space
-        $username = trim($username);
-
-        $sanitised = 1;
-    }
-
-    //
-    // deal with duplicate usernames
-    //
-    
-    $count = db_result(db_query("SELECT COUNT(uid) from {users} where name = '%s'", $username));
-    
-    // add number at end of username if it already exists
-    if ($count > 0) {
-        $count++;
-        $username = $username . $count;
-        $name_in_use = db_result(db_query("SELECT uid from {users} where name = '%s' LIMIT 1", $username));
-        // loop until name is valid
-        if (!empty($name_in_use)) _user_import_sanitise_username($username);
-    }
-    
-    
-    $sanitised = 0;
+      $form['field_match'][$row]['username'] = array(
+          '#type' => 'select',
+          '#default_value' => ($import['field_match'][$row]['username']) ? $import['field_match'][$row]['username'] : $sort[0],
+          '#options' => $sort,
+      );
 
-    return;
-}
+      $form['field_match'][$row]['abbreviate'] = array(
+          '#type' => 'checkbox',
+          '#default_value' => ($import['field_match'][$row]['abbreviate']) ? $import['field_match'][$row]['abbreviate'] : NULL,
+      );
 
-function _user_import_validate_email($email = NULL) {
+      $row++;
+  }
 
-    if (!$email) return 'no email';
-    
-    if (!valid_email_address($email)) return 'invalid email';
-    
-    $result = db_result(db_query("SELECT uid from {users} where mail= '%s' LIMIT 1", $email));
-    if ($result) return 'duplicate email';
- 
-    return;
+  return;
 }
 
-function _user_import_save_profile($field, $uid, $value) {
-    
-    $profile = db_query("INSERT INTO {profile_values} (fid,uid,value) VALUES(%d,%d,'%s')", $field, $uid, $value);
-    return;
-}
+function _user_import_create_username($order, $data, $abbreviate, $username_space) {
 
-// Send email when account is created    
-function _user_import_send_email($account, $password, $profile, $subject, $body, $format, $css, $subscribed) {
+    if (is_array($order)) {
 
-    global $base_url;
-    $from = variable_get('site_mail', ini_get('sendmail_from'));
-    
-    $variables = array(
-      '!username' => $account->name, 
-      '!uid' => $account->uid, 
-      '!site' => variable_get('site_name', 'drupal'), 
-      '!login_url' => user_pass_reset_url($account), 
-      '!password' => $password, 
-      '!uri' => $base_url, 
-      '!uri_brief' => drupal_substr($base_url, drupal_strlen('http://')), 
-      '!mailto' => $account->mail, 
-      '!date' => format_date(time()), 
-      '!login_uri' => url('user', NULL, NULL, TRUE), 
-      '!edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE),
-    );
-    
-    if (module_exists('publication') && module_exists('schedule') && module_exists('identity_hash')) {
+      asort($order);
+      reset($order);
 
-      $id_hash = identity_hash_select_hash($account->uid);
-      $variables['!id_hash'] = $id_hash->hash;
-      
-      while (list($type, $subscriptions) = each($subscribed)) {
-
-        while (list($publication_id, $shedule) = each($subscriptions)) {
-
-          if (!empty($shedule[0])) {
-
-            $publication = publication_select_publications($type, $publication_id);
-            
-            $update_link = url('subscribed/preferences/' . $publication_id . '/' . $id_hash->hash, NULL, NULL, TRUE);
-            $unsubscribe_link = url('subscribed/delete/' . $publication_id . '/' . $id_hash->hash, NULL, NULL, TRUE);
-            
-            if ($format == 1) {
-             
-              $variables['!subscribed_links'] .= '<strong>' . $publication['title'] . '</strong><br />' .
-              '<a href="' . $update_link . '">' . t('Update Preferences') . '</a> | <a href="' . $unsubscribe_link . '">' . t('Unsubscribe') . '</a><br />';
+      $username = '';
 
-            }
-            else {
-            
-              $variables['!subscribed_links'] .= $publication['title'] . "\n" .
-              ' - ' . t('Update Preferences') . ' ' . $update_link . '\n' .
-              ' - ' . t('Unsubscribe') . ' ' . $unsubscribe_link . '\n';
-            
-            }
-          }
-        }
-      }
-    }
+      while (list ($file_column, $sequence) = each ($order)) {
 
-    // import info to profile
-    if (module_exists('profile') && is_array($profile)) {
-      
-      $profile_name = _user_import_profile('fid', 'name');
-      
-      while (list ($fid, $field_name) = each ($profile_name)) {
-        $variables['!' . $field_name] = $profile[$fid];
+          if (!empty($username) && !empty($username_space)) $username .= ' ';
+          $username .= ($abbreviate[$file_column] == 1) ? trim(drupal_strtoupper(chr(ord($data[$file_column])))) : trim($data[$file_column]);
       }
     }
 
-    $subject = (empty($subject)) ? _user_mail_text('welcome_subject', $variables) : strtr($subject, $variables);
-    $subject = mime_header_encode($subject);
-    $body = (empty($body)) ? _user_mail_text('welcome_body', $variables) : strtr($body, $variables);
-    $body = str_replace("\r", '', $body);
-    
-    $header = "From: $from\n";
-    $header .= "Reply-to: $from\n";
-    $header .= "X-Mailer: Drupal\n";
-    $header .= "Return-path: $from\n";
-    $header .= "Errors-to: $from\n";
-    $header .= 'MIME-Version: 1.0';
-    $header .= "\n"; 
-
-    if ($format == 1) {
-      
-      $header .= 'Content-Type: text/html; charset=UTF-8; Content-transfer-encoding: 8Bit'; 
-      
-      $body_head = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-              <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
-              <head>
-              <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />';
-              
-      if (!empty($css)) $body_head .= '<style type="text/css">' . check_plain($css) . '</style>';
-    
-      $body = $body_head . '</head><body>' . $body . '<body></html>';
-      
-    } else {
-      $header .= 'Content-Type: text/plain; charset=UTF-8; format=flowed Content-transfer-encoding: 8Bit';
-    }
+    if (empty($username)) $username = _user_import_random_username();
 
-    mail($account->mail, $subject, $body, $header);
-    return;
+    $username = _user_import_sanitise_username($username);
+    $username = _user_import_unique_username($username);
+    return $username;
+}
+
+/**
+ *  conform to Drupal username rules
+ */
+function _user_import_sanitise_username($username) {
+
+  // username cannot contain an illegal character
+  $username = preg_replace('/[^a-zA-Z0-9@ ]/', ' ', $username);
+  // username cannot contain multiple spaces in a row
+  $username = preg_replace('/[ ]+/', ' ', $username);
+
+  // username must be less than 56 characters
+  $username = drupal_substr($username, 0, 56);
+
+  // username cannot begin or end with a space
+  $username = trim($username);
+  return $username;
+}
+
+/**
+ *  deal with duplicate usernames
+ */
+function _user_import_unique_username($username) {
+
+  static $suffix = 1;
+
+  if ($suffix < 2) {
+    $duplicate = db_result(db_query_range("SELECT uid from {users} where name = '%s'", $username, 0, 1));
+  }
+  else {
+    $usern = $username .' '. $suffix;
+    $duplicate = db_result(db_query_range("SELECT uid from {users} where name = '%s'", $usern, 0, 1));
+  }
+
+  // loop until name is valid
+  if (!empty($duplicate)) {
+    $suffix++;
+    _user_import_unique_username($username);
+  }
+
+  // add number at end of username if it already exists
+  $username = ($suffix < 2) ? $username : "$username $suffix";
+  return $username;
 }
 
 function _user_import_profile($key = 'fid', $return_value = NULL) {
-    
-    if (!module_exists('profile')) return; 
-    
+
+    if (!module_exists('profile')) return;
+
     static $fields_static;
-    
+
     // avoid making more than one database call for profile info
     if (empty($fields_static)) {
-    
+
         $results = db_query("SELECT * FROM {profile_fields}");
-                
-        while ($row = db_fetch_object($results)) { 
+
+        while ($row = db_fetch_object($results)) {
             // don't include private fields
             if (user_access('administer users') || $row->visibility != PROFILE_PRIVATE) {
                 $fields_static[] = $row;
@@ -1341,92 +1190,95 @@ function _user_import_profile($key = 'fi
     }
 
     if (empty($fields_static)) return;
-   
+
     // return all profile fields info, or just specific type
     if (empty($return_value)) {
-        
+
         foreach ($fields_static as $field) {
             $fields[$field->{$key}] = $field;
         }
-    } 
+    }
     else {
         foreach ($fields_static as $field) {
             $fields[$field->{$key}] = $field->{$return_value};
         }
     }
-    
-    asort($fields);    
+
+    asort($fields);
     return $fields;
 }
 
-function _user_import_settings_save($settings, $messages = NULL) {
- 
-     // move settings into 'options' column
-     // 'options' column will be used to store new control options - instead of creating a new column for each option
+function _user_import_settings_save($settings) {
+
+    // move settings into 'options' column
+    // 'options' column will be used to store new control options - instead of creating a new column for each option
     $settings['options']['groups'] = $settings['groups'];
     $settings['options']['existing_og_subscribe'] = $settings['existing_og_subscribe'];
     $settings['options']['existing_og_subject'] = $settings['existing_og_subject'];
     $settings['options']['existing_og_markup'] = $settings['existing_og_markup'];
     $settings['options']['existing_og_message'] = $settings['existing_og_message'];
-    $settings['options']['existing_og_css'] = $settings['existing_og_css'];   
+    $settings['options']['existing_og_css'] = $settings['existing_og_css'];
 
     $settings['options']['subject'] = $settings['subject'];
     $settings['options']['message'] = $settings['message'];
     $settings['options']['message_format'] = $settings['message_format'];
     $settings['options']['message_css'] = $settings['message_css'];
-    
+
     $settings['options']['activate'] = $settings['activate'];
     $settings['options']['subscribed'] = $settings['subscribed'];
-    
+    $settings['options']['update_users'] = $settings['update_users'];
+
     // Update settings for existing import
     if ($settings['import_id']) {
-    
-        db_query("UPDATE {user_import} 
-            SET name = '%s', filename = '%s', oldfilename = '%s', filepath = '%s', pointer = %d, processed = %d, valid= %d, first_line_skip = %d, contact = %d, username_space = %d, send_email = %d, field_match = '%s', roles = '%s', options = '%s', setting = '%s' 
+
+        db_query("UPDATE {user_import}
+            SET name = '%s', filename = '%s', oldfilename = '%s', filepath = '%s', pointer = %d, processed = %d, valid= %d, first_line_skip = %d, contact = %d, username_space = %d, send_email = %d, field_match = '%s', roles = '%s', options = '%s', setting = '%s'
             WHERE import_id = %d
             ", trim($settings['name']), $settings['filename'], $settings['oldfilename'], $settings['filepath'], $settings['pointer'], $settings['processed'], $settings['valid'], $settings['first_line_skip'], $settings['contact'], $settings['username_space'], $settings['send_email'], serialize($settings['field_match']), serialize($settings['roles']), serialize($settings['options']), $settings['setting'], $settings['import_id']);
-        
+
         // Save settings for new import
-    } 
+    }
     else {
-    
-        db_query("INSERT INTO {user_import} 
-            (name, filename, oldfilename, filepath, started, pointer, processed, valid, first_line_skip, contact, username_space, send_email, field_match, roles, options, setting) 
+
+        db_query("INSERT INTO {user_import}
+            (name, filename, oldfilename, filepath, started, pointer, processed, valid, first_line_skip, contact, username_space, send_email, field_match, roles, options, setting)
             VALUES ('%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s')
             ", trim($settings['name']), $settings['filename'], $settings['oldfilename'], $settings['filepath'], time(), $settings['pointer'], $settings['processed'], $settings['valid'], $settings['first_line_skip'], $settings['contact'], $settings['username_space'], $settings['send_email'], serialize($settings['field_match']), serialize($settings['roles']), serialize($settings['options']), $settings['setting']);
-            
+
         $settings['import_id'] = db_result(db_query("SELECT LAST_INSERT_ID()"));
     }
-    
+
     return $settings;
 }
 
-function _user_import_errors_save($import_id, $data, $email, $error) {
+// Update settings for existing import
+function _user_import_settings_update($pointer, $processed, $valid, $setting, $import_id) {
 
-    $data['email'] = $email;
+  if (empty($import_id)) return;
+  db_query("UPDATE {user_import} SET pointer = %d, processed = %d, valid= %d, setting = '%s' WHERE import_id = %d", $pointer, $processed, $valid, $setting, $import_id);
+}
 
-    db_query("INSERT INTO {user_import_errors} 
-        (import_id, data, error) 
-        VALUES (%d, '%s', '%s')
-        ", $import_id, serialize($data), $error);
-     return;
+function _user_import_errors_display_save($import_id, $data, $email, $errors) {
+  $data['email'] = $email;
+  db_query("INSERT INTO {user_import_errors} (import_id, data, errors) VALUES (%d, '%s', '%s')", $import_id, serialize($data), serialize($errors));
+  return;
 }
 
 function _user_import_settings_select($import_id = NULL, $template = FALSE) {
-         
+
     if (!empty($import_id) && !is_numeric($import_id)) return;
-    
+
     if (!empty($import_id)) {
-    
-        $import = db_fetch_array(db_query("SELECT * FROM {user_import} WHERE import_id = %d LIMIT 1", $import_id));
+
+        $import = db_fetch_array(db_query_range("SELECT * FROM {user_import} WHERE import_id = %d", $import_id, 0, 1));
         $import['field_match'] = unserialize($import['field_match']);
         $import['roles'] = unserialize($import['roles']);
         $import['options'] = unserialize($import['options']);
-    
-    } 
+
+    }
     else {
-        
-        $query = ($template) ? "SELECT * FROM {user_import} WHERE setting = 'template'" : "SELECT * FROM {user_import} WHERE setting != 'template' ORDER BY started DESC";
+
+        $query = ($template) ? "SELECT * FROM {user_import} WHERE setting = 'template'" : "SELECT * FROM {user_import} WHERE setting <> 'template' ORDER BY started DESC";
         $results = db_query($query);
         while ($row = db_fetch_array($results)) {
             $row['field_match'] = unserialize($row['field_match']);
@@ -1435,8 +1287,8 @@ function _user_import_settings_select($i
             $import[] = $row;
         }
     }
-      
-    return $import;      
+
+    return $import;
 }
 
 function _user_import_settings_deletion($import_id) {
@@ -1451,73 +1303,74 @@ function _user_import_random_username() 
     $vowels = 'aoueiy';
     $consonants = 'bcdfghjklmnpqrstvwxz';
     $length = 8;
-    
-    mt_srand ((double) microtime() * 10000000);
+
+    mt_srand((double) microtime() * 10000000);
     $next_vowel = 0;
-    
+
     for ($count = 0; $count <= $length; $count++) {
 
         if ($next_vowel) {
             $rand = mt_rand(0, 5);
-            $username.= $vowels{$rand};
+            $username .= $vowels{$rand};
             $next_vowel = 0;
-    
-        } 
+
+        }
         else {
             $rand = mt_rand(0, 19);
             $username .= $consonants{$rand};
             $next_vowel = 1;
         }
     }
-    
+
     return $username;
 }
 
 // Clean file - in case of incompatable line endings
 function _user_import_file_cleaner($filepath) {
 
-    $file = fopen($filepath,'r+');
-    while (!feof($file )){
-       $line = chop(fgets($file,4096));
-       $return = ereg_replace(chr(13) . chr(10), "\n", $line);
-       $return = ereg_replace(chr(13), "\n", $return);
-       fwrite($file, $return);
+    $file = fopen($filepath, 'r+');
+    while (!feof($file)) {
+      $line = chop(fgets($file, 4096));
+      $return = ereg_replace(chr(13) . chr(10), "\n", $line);
+      $return = ereg_replace(chr(13), "\n", $return);
+      fwrite($file, $return);
     }
-    
+
     fclose($file);
     return;
 }
-	
-function _user_import_process($settings) {	
 
-    $user_import_line_max = variable_get('user_import_line_max', 1000);
-    
-    // get enabled roles
-    while (list ($rid, $role_set) = each ($settings['roles'])) {
-        if (!empty($role_set)) $roles[$rid] = $rid;
-    }
+function _user_import_process($settings) {
+
+    user_import_load_supported();
+    $line_max = variable_get('user_import_line_max', 1000);
+    $import_max = variable_get('user_import_max', 250);
+    $field_match = _user_import_unconcatenate_field_match($settings['field_match']);
 
     $handle = @fopen($settings['filepath'], "r");
-    
+
     // move pointer to where test/import last finished
     if ($settings['pointer'] != 0) fseek ($handle, $settings['pointer']);
-  
+
     // start count of imports on this cron run
     $send_counter = 0;
-    
-    while ($data = fgetcsv($handle, $user_import_line_max, ',')) {
-    
+    $password = '';
+    $fields = '';
+    while ($data = fgetcsv($handle, $line_max, ',')) {
+
+        $errors = user_import_errors(FALSE, TRUE);
+
         // if importing, check we are not over max number of imports per cron
-        if ($settings['setting'] == 'import' && $send_counter > variable_get('user_import_max', 250)) {
+        if ($settings['setting'] == 'import' && $send_counter > $import_max) {
             $finished = TRUE;
             break;
         }
 
         // don't process empty lines
         $line_filled = (count($data) == 1 && drupal_strlen($data[0]) == 0) ? FALSE : TRUE;
-        
+
         if ($line_filled) {
-        
+
             // check if this is first line - if so should we skip?
             if (!empty($settings['first_line_skip']) && $settings['processed'] == 0) {
                 // reset to false on second process
@@ -1526,120 +1379,103 @@ function _user_import_process($settings)
 
             if (!$first_line_skip) {
 
-                unset($email);
-                unset($password);
-                unset($errors);
-                unset($fields);
-                reset($settings['field_match']);
-
-                while (list ($column_id, $setting) = each ($settings['field_match'])) {
-                
-                    if ($setting['field_match'] == 'email') {
-                        $email = trim($data[$column_id]);
-                        $errors = _user_import_validate_email($email);
+                unset($password, $errors, $fields);
+                reset($field_match);
+
+                foreach ($field_match as $column_id => $column_settings) {
+
+                    $type = $column_settings['type'];
+                    $field_id = $column_settings['field_id'];
+
+                    // Skip if this is a field used as part of a username but
+                    // not otherwise mapped for import.
+                    if ($type != 'username_part') {
+                      $fields[$type][$field_id] = module_invoke_all('user_import_data', $settings, $column_settings, $type, $field_id, $data, $column_id);
                     }
-                    
-                    if ($setting['field_match'] == 'password') $password = trim($data[$column_id]);
-            
-                    if ($setting['field_match'] != 0 && $setting['field_match'] != 'email' && $setting['field_match'] != 'password') $fields[$setting['field_match']] = $data[$column_id];
-                    
-                    if ($setting['username'] > 0) {
-                            
-                            $username_data[$column_id]= $data[$column_id];
-                            $username_order[ $column_id ] = $setting['username'];
-                            $username_abbreviate[$column_id]= $setting['abbreviate'];
-                    } 
+                    // Read in data if present for concatenating a user name.
+                    if ($column_settings['username'] > 0) {
+
+                        $username_data[$column_id] = $data[$column_id];
+                        $username_order[$column_id] = $column_settings['username'];
+                        $username_abbreviate[$column_id]= $column_settings['abbreviate'];
+                    }
+
+                }
+
+                $errors = user_import_errors();
+                $account = array();
+
+                if ($fields['user']['delete'][0] == 'yes') {
+                  $existing = user_load(array('mail' => $fields['user']['email'][0]));
+                  user_delete($existing, $existing->uid);
+                  continue;
+                }
+
+                $account_additions = module_invoke_all('user_import_pre_save', $settings, $account, NULL, $fields, $errors);
+
+                foreach ($account_additions as $field_name => $value) {
+                  $account[$field_name] = $value;
                 }
-                
-                if ($errors == 'duplicate email' && $settings['setting'] == 'import') _user_import_group_add($settings, $email, $fields);
 
-                if (!$errors) {
-                    
+                if (empty($errors)) {
                     if ($settings['setting'] == 'import') {
-                        
-                        $username = _user_import_create_username($username_order, $username_data, $username_abbreviate, $settings['username_space']);
-                        
-                        if (empty($password)) $password = user_password();
-                        if ($settings['contact'] == 1) $contact = 1;
-
-                        $account = array(
-                            'name' => $username,
-                            'pass' => $password,
-                            'mail' => $email,
-                            'init' => $email,
-                            'timezone' => '-18000',
-                            'status' => 1,
-                            'roles' => $roles,
-                            'contact' => $contact
-                         );
-                         
-                         if (!empty($settings['options']['activate'])) {
-                            $account['access'] = time();
-                            $account['login'] = time();
-                         }
-            
-                        $account = user_save('', $account);
-                        watchdog('user', t('New user: %name %email.', array('%name' => theme('placeholder', check_plain($account->name)), '%email' => theme('placeholder', '<'. check_plain($account->mail) .'>'))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
-                     
-                        // import info to profile
-                        if (is_array($fields)) {
-                            while (list ($fid, $content) = each ($fields)) {
-                                _user_import_save_profile($fid, $account->uid, trim($content));
-                            }
+                        // If we update existing users matched by email (and
+                        // therefore passed validation even if this email
+                        // already exists), look for and use an existing account.
+
+                        if (!empty($settings['options']['update_users']) && $existing = user_load(array('mail' => $account['mail']))) {
+                          $account = user_save($existing, $account);
                         }
-    
-                        _user_import_organic_groups($settings['options']['groups'], $account->uid);
-                        _user_import_subscribed($settings['options']['subscribed'], $account->uid);
-                        
-                        if (!empty($settings['send_email'])) _user_import_send_email($account, $password, $fields, $settings['options']['subject'], $settings['options']['message'], $settings['options']['message_format'], $settings['options']['message_css'], $settings['options']['subscribed']);
+                        else {
+                          // Only set a user name if we are not updating an existing record.
+                          $account['name'] = _user_import_create_username($username_order, $username_data, $username_abbreviate, $settings['username_space']);
+                          $account = user_save('', $account);
+                        }
+                        module_invoke_all('user_import_after_save', $settings, $account, $password, $fields);
                         $send_counter++;
-    
                     }
-                    
+
                     $settings['valid']++;
                 }
-            
+
                 $settings['processed']++;
- 
             }
-        
+
             $settings['pointer'] = ftell($handle);
-        
+
             // save lines that have fatal errors
-            if ($errors) _user_import_errors_save($settings['import_id'], $fields, $email, $errors);
-            
+            if (!empty($errors)) _user_import_errors_display_save($settings['import_id'], $fields, $account['email'], $errors);
         }
     }
-    
-    fclose ($handle);
+
+    fclose($handle);
     if ($settings['setting'] == 'import' && !$finished) $settings['setting'] = 'imported';
     if ($settings['setting'] == 'test') $settings['setting'] = 'tested';
-    $settings = _user_import_settings_save($settings);
-    
+    _user_import_settings_update($settings['pointer'], $settings['processed'], $settings['valid'], $settings['setting'], $settings['import_id']);
     return $settings;
 }
 
 function user_import_usernames_invalid($delete = NULL) {
-    
-    $users = db_query("SELECT uid, name, mail from {users} WHERE uid != 0 AND uid != 1");
-    
+
+    $users = db_query("SELECT uid, name, mail from {users} WHERE uid <> 0 AND uid <> 1");
+
     while ($user = db_fetch_object($users)) {
-        
+
         $error = user_validate_name($user->name);
-        
+
         if (!empty($error)) {
             $errors[$user->uid]['uid'] = $user->uid;
             $errors[$user->uid]['mail'] = $user->mail;
             $errors[$user->uid]['name'] = $user->name;
             $errors[$user->uid]['error'] = $error;
-            
+
             if (!empty($delete)) {
-                $form_values['account'] = $user;
-                user_confirm_delete_submit($form_id, $form_values);
+                $form_state['values']['account'] = $user;
+                user_confirm_delete_submit($form, $form_state['values']);
             }
         }
     }
-    
+
     $output = theme('user_import_username_errors', $errors);
     return $output;
 }
@@ -1647,12 +1483,12 @@ function user_import_usernames_invalid($
 function _user_import_file_deletion($filepath, $filename, $old_filename, $message = TRUE) {
 
     $removed = file_delete($filepath);
-    
+
     if (!$message) return;
-    
+
     if (empty($removed)) {
-        drupal_set_message(t("File error: file '%old_filename' (%filename) could not be deleted.", array('%old_filename' => $oldfilename, '%filename' => $filename)), 'error');
-    } 
+        drupal_set_message(t("File error: file '%old_filename' (%filename) could not be deleted.", array('%old_filename' => $old_filename, '%filename' => $filename)), 'error');
+    }
     else {
         drupal_set_message(t("File '%old_filename' was deleted.", array('%old_filename' => $old_filename)));
     }
@@ -1668,7 +1504,7 @@ function _user_import_initialise_import(
         case 'imported':
             drupal_set_message(t('File has already been imported'), 'error');
             break;
-       
+
         // add setting template values to new import settings
         case 'file set':
             if (empty($import['template_id'])) return $import;
@@ -1680,7 +1516,7 @@ function _user_import_initialise_import(
             $template['started'] = 0;
             $template['setting'] = 'file set';
             return $template;
-            
+
         case 'test':
         case 'tested':
             $import['setting'] = 'import';
@@ -1688,11 +1524,11 @@ function _user_import_initialise_import(
             $import['pointer'] = 0;
             $import['processed'] = 0;
             $import['valid'] = 0;
-            _user_import_errors_delete($import['import_id']);
+            _user_import_errors_display_delete($import['import_id']);
             _user_import_settings_save($import);
             _user_import_process($import);
             break;
-            
+
         case 'template':
             unset($import['filename']);
             unset($import['oldfilename']);
@@ -1703,94 +1539,94 @@ function _user_import_initialise_import(
             $import['valid'] = 0;
             _user_import_settings_save($import);
             break;
-            
+
         default:
             _user_import_process($import);
             drupal_set_message(t('Imported'));
             break;
     }
-    
+
     return;
 }
 
-function _user_import_errors_delete($import_id) {
+function _user_import_errors_display_delete($import_id) {
 
     db_query("DELETE FROM {user_import_errors} WHERE import_id = %d", $import_id);
     return;
 }
 
-/*
-// File being used
-// $import_id - use file info stored in database
-// $ftp_file - chosen from FTP uploaded files
-// $uploaded_file - uploaded through browser
-*/
-function _user_import_file($import_id = NULL, $ftp_file_selected = NULL) { 
-
-    static $file;
-    if ( !empty($file) ) return $file;
-    
-    // file was uploaded through browser
-    $file = file_check_upload('file_upload');
-    if ( !empty($file) ) return $file;
-    
-    // file was uploaded by FTP
-    if ( !empty($ftp_file_selected) ) {    
-        $ftp_files = _user_import_ftp_files();
-        $filepath = drupal_get_path('module', 'user_import');
-        $filename = $ftp_files[$ftp_file_selected];
-        $file->filepath = "$filepath/$filename";
-        $file->filename = $filename;
-        return $file;
-    }
-    
-   // use file info stored in database
-   if (!empty($import_id)) {
-        $import = _user_import_settings_select($import_id);
-        $file->filepath = $import['filepath'];
-        $file->oldfilename = $import['oldfilename'];
-        $file->filename = $import['filename'];
-        return $file;
-   }
-    
-    return;   
+/**
+ * File being used
+ * $import_id - use file info stored in database
+ * $ftp_file - chosen from FTP uploaded files
+ * $uploaded_file - uploaded through browser
+ */
+
+function _user_import_file($import_id = NULL, $ftp_file_selected = NULL) {
+
+  static $file;
+  if ( !empty($file) ) return $file;
+
+  // file was uploaded through browser
+  $file = file_save_upload('file_upload', array());
+  if ( !empty($file) ) return $file;
+
+  // file was uploaded by FTP
+  if ( !empty($ftp_file_selected) ) {
+    $ftp_files = _user_import_ftp_files();
+    $filepath = drupal_get_path('module', 'user_import');
+    $filename = $ftp_files[$ftp_file_selected];
+    $file = new stdClass();
+    $file->filepath = "$filepath/$filename";
+    $file->filename = $filename;
+    return $file;
+  }
+
+  // use file info stored in database
+  if (!empty($import_id)) {
+    $import = _user_import_settings_select($import_id);
+    $file->filepath = $import['filepath'];
+    $file->oldfilename = $import['oldfilename'];
+    $file->filename = $import['filename'];
+    return $file;
+  }
+
+  return;
 }
 
 // open file
 function _user_import_file_open($filepath, $filename) {
-    
-    static $handle;
-    if (!empty($handle)) return $handle;
-    
-    $handle = @fopen($filepath, "r");
-                        
-    if (!$handle) {
-        form_set_error('file', t("Could not find the csv file '%filename'", array('%filename' => $filename)), 'error');
-        return t("Please add your file again.");
-    }
-    return $handle;
+  static $handle;
+  if (!empty($handle)) return $handle;
+
+  $handle = @fopen($filepath, "r");
+
+  if (!$handle) {
+    form_set_error('file', t("Could not find the csv file '%filename'", array('%filename' => $filename)), 'error');
+    return t("Please add your file again.");
+  }
+  return $handle;
 }
 
 // get first row of file
 function _user_import_file_row($filename, $handle) {
-    
-    $data_row = @fgetcsv ($handle, 1000000, ",");
-    if (!$data_row) {
-        form_set_error('file', t("Could not get data, the file '%filename' is either empty or has incompatible line endings.", array('%filename' => $filename)), 'error');
-    }
-    return $data_row;
+  $data_row = @fgetcsv ($handle, 1000000, ",");
+  if (!$data_row) {
+    form_set_error('file', t("Could not get data, the file '%filename' is either empty or has incompatible line endings.", array('%filename' => $filename)), 'error');
+  }
+  return $data_row;
 }
 
 // get info on files  uploaded via FTP
 function _user_import_ftp_files() {
-  
+
   $directory = opendir( drupal_get_path('module', 'user_import') );
   $filenames[] = t('none');
-  
+
   while ($file = readdir($directory)) {
-    if ($file != '.' && $file != '..' && $file != '.DS_Store' && $file != 'CVS' && $file != 'README.txt' && $file != 'UPDATES.txt' && $file != 'user_import.module' && $file != 'user_import.mysql' && $file != 'user_import.install' && $file != 'user_import.info') $filenames[] = $file;
+    if ($file != '.' && $file != '..' && $file != '.DS_Store' && $file != 'CVS' && $file != '.svn' && $file != 'README.txt' && $file != 'UPDATES.txt' && $file != 'user_import.module' && $file != 'user_import.mysql' && $file != 'user_import.install' && $file != 'user_import.info' && $file != 'supported') $filenames[] = $file;
   }
-  
+
   closedir($directory);
   return $filenames;
 }
@@ -1798,112 +1634,67 @@ function _user_import_ftp_files() {
 // delete incomplete import settings, where only the file has been uploaded
 function  _user_import_incomplete_deletion() {
 
-    $results =db_query("SELECT * FROM {user_import} WHERE setting = 'file set'");
-    
-    while ($import = db_fetch_object($results)) {
-    
-        _user_import_file_deletion($import->filepath, $import->filename, $import->oldfilename, FALSE);
-        _user_import_settings_deletion($import->import_id);
-    }
-    
-    return;
+  $results =db_query("SELECT * FROM {user_import} WHERE setting = 'file set'");
+
+  while ($import = db_fetch_object($results)) {
+    _user_import_file_deletion($import->filepath, $import->filename, $import->oldfilename, FALSE);
+    _user_import_settings_deletion($import->import_id);
+  }
+
+  return;
 }
 
 // get info of existing groups
 function user_import_get_groups() {
+  $og_type = variable_get('og_node_types', array('og'));
 
-    $og_type = variable_get('og_node_types', array('og'));
+  $results = db_query("SELECT
+                     n.nid, n.title FROM {node} n INNER JOIN {og} og ON n.nid = og.nid
+                     WHERE n.status = 1 AND n.type IN ('%s')
+                     ORDER BY n.title", $og_type);
 
-     $results = db_query("SELECT 
-                     n.nid, n.title FROM {node} n INNER JOIN {og} og ON n.nid = og.nid 
-                     WHERE n.status = 1 AND n.type IN ('%s')  
-                     ORDER BY n.title", $og_type);           
-                
-    while ($group = db_fetch_object($results)) {
-    
-        $groups[$group->nid] = $group->title;
-    }
-    
-    return $groups;
+  while ($group = db_fetch_object($results)) {
+    $groups[$group->nid] = $group->title;
+  }
+
+  return $groups;
 }
 
+/*
+
+CRUFT ??
+
 // add user to groups
 function _user_import_organic_groups($groups_selected, $uid) {
 
     if (!module_exists('og')) return;
-     
+
     $organic_groups = user_import_get_groups();
     if(empty($organic_groups)) return;
-    
+
     $og_args = array('is_active' => 1, 'is_admin' => 0, 'mail_type' => 0, 'created' => time());
 
     while(list($gid, $title) = each($organic_groups)) {
-    
+
         if (!empty($groups_selected[$gid])) og_save_subscription($gid, $uid, $og_args);
     }
-    
-    return;
-}
-
-
-// add user subscriptions
-function _user_import_subscribed($subscribed, $uid) {
-
-    if (!module_exists('publication') || !module_exists('schedule') || !module_exists('identity_hash')) return;
 
-    while (list($type, $subscriptions) = each($subscribed)) {
-  
-      $publications = publication_select_publications_and_terms($type);
-
-      if (!empty($publications)) {
-
-        subscribed_set_subscriptions($type, $uid, $publications, $subscriptions);
-        subscribed_set_subscriptions_terms($type, $uid, $publications, $subscriptions); 
-        identity_hash_set_hash($uid);
-      }
-    
-    }
-    
     return;
 }
 
-// add user to groups if already a member
-function _user_import_group_add($settings, $email, $fields) {
-
-  if (!module_exists('og')) return;
-  
-  $account = user_load(array('mail' => $email));
-  if (!empty($settings['options']['existing_og_message'])) $profile = user_import_profile_load($account);
-
-  $groups_subscribed = og_get_subscriptions($account->uid);
-  
-  foreach($settings['groups'] as $group) {
-    
-    // is user member of group?
-    if (!empty($group) && empty($groups_subscribed[$group])) {
-      
-      // subscribe to group
-      og_subscribe_user($group, $account);
 
-      if (!empty($settings['options']['existing_og_message'])) _user_import_send_email($account, $password, $profile, $settings['options']['existing_og_subject'], $settings['options']['existing_og_message'], $settings['options']['existing_og_markup'], $settings['options']['existing_og_css'], $settings['options']['subscribed']);
-      
-    }
+ */
 
-  }
 
-    return;
-}
+function user_import_profile_string($prefix = ',') {
 
+  if (!module_exists('profile')) return;
 
-function user_import_profile_string($prefix = ',') {
+  $profile_fields = _user_import_profile('fid', 'name');
 
-    if (!module_exists('profile')) return;
-    
-    $profile_fields = _user_import_profile('fid', 'name');
-    
-    if (!empty($profile_fields)) $profile_string = ', !' . implode($prefix .' !', $profile_fields);
+  if (!empty($profile_fields)) $profile_string = ', !'. implode($prefix .' !', $profile_fields);
 
-    return $profile_string;
+  return $profile_string;
 }
 
 function user_import_profile_load($user) {
@@ -1911,72 +1702,67 @@ function user_import_profile_load($user)
   $result = db_query('SELECT f.name, f.type, f.fid, v.value FROM {profile_fields} f INNER JOIN {profile_values} v ON f.fid = v.fid WHERE uid = %d', $user->uid);
 
   while ($field = db_fetch_object($result)) {
-  
+
     if (empty($profile[$field->fid])) {
-      
+
       $profile[$field->fid] = _profile_field_serialize($field->type) ? unserialize($field->value) : $field->value;
     }
-    
+
   }
-  
+
   return $profile;
 }
 
-function user_import_edit_subscribed_fields(&$form, $import) {
-
-  if (module_exists('publication') && module_exists('schedule')) {
+function _user_import_unconcatenate_field_match($settings) {
 
-    $publications = publication_select_publications('enewsletter');
-    if (empty($publications)) return;
+  $settings_updated = array();
+  foreach ($settings as $column_id => $values) {
 
-    $form['subscribed'] = array(
-        '#type' => 'fieldset',
-        '#title' => t('Subscriptions'),
-        '#collapsible' => TRUE,
-        '#collapsed' => $collapsed,
-        '#tree' => TRUE,
-    );
-    
-    foreach ($publications as $publication) {
-    
-      $type = $publication['type'];
-      
-      $form['subscribed'][$type] = array(
-          '#type' => 'fieldset',
-          '#title' => check_plain($type),
-      );
-      
-    }
-    
-    reset($publications);
-    $subscribed = $import['options']['subscribed'];
- 
-    foreach ($publications as $publication) {
-      
-      $options = array();
-      $schedules = schedule_select_schedules($type, $publication['publication_id']);
-      $options[0] = t('No Subscription');
-      
-      foreach ($schedules as $schedule) {                     
-        $options[ $schedule['schedule_id'] ] = $schedule['schedule_title'];
+    if (!empty($values['field_match']) || !empty($values['username'])) {
+      // If we have a username but no field_match, set a special type.
+      // This allows us to skip saving the field but still use it in
+      // concatenating a username value.
+      if (empty($values['field_match'])) {
+        $values['type'] = 'username_part';
+        $values['field_id'] = 'username_part_'. $column_id;
       }
-
-      $subscription_default = empty($subscribed[$type][$publication['publication_id']]) ? 0 : $subscribed[$type][$publication['publication_id']][0];
-
-      $form['subscribed'][$type][$publication['publication_id']][] = array(
-        '#type' => 'radios',
-        '#title' => check_plain($publication['title']),
-        '#default_value' => $subscription_default,
-        '#options' => $options,
-        '#description' => check_plain($publication['description']),
-      );
-      
+      else {
+        $key_parts = explode('-', $values['field_match']);
+        $values['type'] = array_shift($key_parts);
+        $values['field_id'] = implode('-', $key_parts);
+      }
+      unset($values['field_match']);
+      $settings_updated[$column_id] = $values;
     }
-    
-  
   }
-  
-  return;
+
+  return $settings_updated;
 }
 
+/**
+ * Return an existing user ID, if present, for a given email.
+ */
+function _user_import_existing_uid($email) {
+  static $uid;
+  if (!isset($uid[$email])) {
+    $uid[$email] = db_result(db_query_range("SELECT uid from {users} where mail= '%s'", $email, 0, 1));
+  }
+  return $uid[$email];
+}
 
+/**
+ * Loads the hooks for the supported modules.
+ */
+function user_import_load_supported() {
+  static $loaded = FALSE;
+  if (!$loaded) {
+    $path = drupal_get_path('module', 'user_import') .'/supported';
+    $files = drupal_system_listing('.*\.inc$', $path, 'name', 0);
+    foreach ($files as $module_name => $file) {
+      if (module_exists($module_name)) {
+        include_once($file->filename);
+      }
+    }
+    $loaded = TRUE;
+  }
+}
Index: user_import.mysql
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/user_import/user_import.mysql,v
retrieving revision 1.5
diff -u -p -r1.5 user_import.mysql
--- user_import.mysql	25 Apr 2006 00:19:51 -0000	1.5
+++ user_import.mysql	17 Oct 2008 17:59:09 -0000
@@ -1 +1,33 @@
-## Table structure for table `user_import`#CREATE TABLE `user_import` (  `iid` int(10) unsigned NOT NULL auto_increment,  `name` varchar(25) NOT NULL default '',  `filename` varchar(50) NOT NULL default '',  `oldfilename` varchar(50) NOT NULL default '',  `filepath` tinytext NOT NULL,  `started` int(11) NOT NULL default '0',  `pointer` int(10) NOT NULL default '0',  `total` int(10) NOT NULL default '0',  `processed` int(10) NOT NULL default '0',  `valid` int(10) NOT NULL default '0',  `first_line` int(1) NOT NULL default '0',  `contact` int(1) NOT NULL default '0',  `username_space` int(1) NOT NULL default '0',  `send_email` int(1) NOT NULL default '0',  `field_match` longtext NOT NULL,  `roles` varchar(255) NOT NULL default '',  `setting` varchar(10) NOT NULL default '',  PRIMARY KEY  (`iid`));# --------------------------------------------------------## Table structure for table `user_import_errors`#CREATE TABLE `user_import_errors` (  `iid` int(10) NOT NULL default '0',  `data` longtext NOT NULL,  `error` varchar(25) NOT NULL default '',  KEY `iid` (`iid`));
\ No newline at end of file
+#
+# Table structure for table `user_import`
+#
+CREATE TABLE `user_import` (
+  `iid` int(10) unsigned NOT NULL auto_increment,
+  `name` varchar(25) NOT NULL default '',
+  `filename` varchar(50) NOT NULL default '',
+  `oldfilename` varchar(50) NOT NULL default '',
+  `filepath` tinytext NOT NULL,
+  `started` int(11) NOT NULL default '0',
+  `pointer` int(10) NOT NULL default '0',
+  `total` int(10) NOT NULL default '0',
+  `processed` int(10) NOT NULL default '0',
+  `valid` int(10) NOT NULL default '0',
+  `first_line` int(1) NOT NULL default '0',
+  `contact` int(1) NOT NULL default '0',
+  `username_space` int(1) NOT NULL default '0',
+  `send_email` int(1) NOT NULL default '0',
+  `field_match` longtext NOT NULL,
+  `roles` varchar(255) NOT NULL default '',
+  `setting` varchar(10) NOT NULL default '',
+  PRIMARY KEY  (`iid`)
+);
+# --------------------------------------------------------
+#
+# Table structure for table `user_import_errors`
+#
+CREATE TABLE `user_import_errors` (
+  `iid` int(10) NOT NULL default '0',
+  `data` longtext NOT NULL,
+  `error` varchar(25) NOT NULL default '',
+  KEY `iid` (`iid`)
+);
