Bulk add users?)

Started by BrianTH, May 08, 2014, 05:16:09 AM

Previous topic - Next topic

Kindred

MailChimp exports do **NOT** include passwords in any way shape or form...


it's a mailing list group (like Constant Contact)
Слaва
Украинi

Please do not PM, IM or Email me with support questions.  You will get better and faster responses in the support boards.  Thank you.

"Loki is not evil, although he is certainly not a force for good. Loki is... complicated."

Arantor

We kind of figured that :P Meaning that for SMF not to have hissy fits, passwords must be generated as part of the import process into SMF itself. And it's insecure to have them all be the same password, and it's not great if there isn't some kind of username that's unique but not an email address...

Kindred

This is the export header
Email Address   First Name   Last Name   MEMBER_RATING   OPTIN_TIME   OPTIN_IP   CONFIRM_TIME   CONFIRM_IP   LATITUDE   LONGITUDE   GMTOFF   DSTOFF   TIMEZONE   CC   REGION   LAST_CHANGED   LEID   EUID   EMAIL_TYPE   MEMBER_RATING   OPTIN_TIME   OPTIN_IP   CONFIRM_TIME   CONFIRM_IP   LATITUDE   LONGITUDE   GMTOFF   DSTOFF   TIMEZONE   CC   REGION   LAST_CHANGED   LEID   EUID
Слaва
Украинi

Please do not PM, IM or Email me with support questions.  You will get better and faster responses in the support boards.  Thank you.

"Loki is not evil, although he is certainly not a force for good. Loki is... complicated."

Arantor

Useful to know. I'm assuming that an importer would use first name and last name, combined, to make a username, but that's not ideal.

Angelina Belle

For the first cut at this, perhaps:
* One CSV import format (to be used for bulk user creation from ANY source: Yahoo group, mailchimp; google group; whatever)
* Up to admin to use spreadsheet program to generate username (= A1 & "_" & B1, for example), then save new CSV file.
Never attribute to malice that which is adequately explained by stupidity. -- Hanlon's Razor

BrianTH

If random passwords are set against each email address and the user then has to add their name and change the password - that would be fine.

But how do I do this?

gigashiga

hi,
there used to be one file called csvimport.php
for older version of smf (it worked perfectly fine with smf version 1.1.18)

it used to take
username,password,emailid 

If anyone can modify it for the version 2.0 I will search it I should have its backup with me.
Its not my code I downloaded it from this website only

gigashiga

Quote from: BrianTH on May 08, 2014, 05:38:46 PM
the emails will be in standard format e.g.

[email protected]
[email protected]
[email protected]

These invitations will be sent out with the password changeme

and yes when members are added you can send email to all the members to reset their passwords using bcc

or using a mailing script < I am also looking for a good FREE mailing script

gigashiga

can someone help me so that this script canbe  modified for version 2.x ?

edit:
I do not take credit for this script, I downloaded it from this forum

Can i share code here ?


margarett

Se forem conduzir, não bebam. Se forem beber... CHAMEM-ME!!!! :D

QuoteOver 90% of all computer problems can be traced back to the interface between the keyboard and the chair

motechman

#30
Quote from: AngelinaBelle on May 08, 2014, 05:47:39 PM
A random password could be chosen for each new account.
Whether they did or not, they would still receive email from their "new mailing list"

Some customized code based mostly on existing register-by-admin and/or "send me an i forgot my password" could be used.

The (register-by-admin) sounds like the way to do it to me. I have a list of members I need to create SMF account for (version 2.07) and have a system generated password emailed to them. My member list has first, last, username, email data, I just need to create a script to run the (index.php?action=admin;area=regcenter).

I've got decades of programming experience in web code and a little of it in PHP. I just need a little orientation and a few pointers to help me do this. Wasn't hard to find that right here on previous forum posts.

I just modified the admin registration code, adding a loop that reads each new member from a file and calls the appropriate functions to do the registrations. I only had 50 members to add so the hack was quite simpe and I had no issues.

OK, I managed to succeed with my import by hacking ManageRegistration.php, which appears below.
This still could use some error processing code. The messages coded will not appear in the UI.

Usage: (requires access to your SMF files on your hosting account)
1) Create a csv file named members.csv with the new members to add.
2) Rename the original ManageRegistration.php to save it.
3) Put the members.csv and this file into the Sources folder of your SMF.
4) Login as SMF administrator and go to Admin=> Features & Options.
5) On the Features & Options menu go to Members=> Registration=> Register New Member
6) Click the Register button (no need to fill in form) to import the new members.
7) Delete or rename this file and restore the original after confirming the new
    members have been added.

Enjoy  ;D


<?php

/**
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines http://www.simplemachines.org
 * @copyright 2011 Simple Machines
 * @license http://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.0
 */

if (!defined('SMF'))
die('Hacking attempt...');

/* This file helps the administrator setting registration settings and policy
as well as allow the administrator to register new members themselves.

void RegCenter()
- entrance point for the registration center.
- accessed by ?action=admin;area=regcenter.
- requires either the moderate_forum or the admin_forum permission.
- loads the Login language file and the Register template.
- calls the right function based on the subaction.

void AdminRegister()
- a function to register new members from a csv file.
- accessed by ?action=admin;area=regcenter;sa=register
- members.csv file must have username, firstname, lastname and email.
- emails user a randomly generated password.
- user is required to activate their account.
- the members are not assigned to any group.
- requires the moderate_forum permission.
- uses the admin_register sub template of the Register template.
- must enter a bogus user and email address to submit form.

void EditAgreement()
- allows the administrator to edit the registration agreement, and
  choose whether it should be shown or not.
- accessed by ?action=admin;area=regcenter;sa=agreement.
- uses the Admin template and the edit_agreement sub template.
- requires the admin_forum permission.
- uses the edit_agreement administration area.
- writes and saves the agreement to the agreement.txt file.

void SetReserve()
- set the names under which users are not allowed to register.
- accessed by ?action=admin;area=regcenter;sa=reservednames.
- requires the admin_forum permission.
- uses the reserved_words sub template of the Register template.

void ModifyRegistrationSettings()
- set general registration settings and Coppa compliance settings.
- accessed by ?action=admin;area=regcenter;sa=settings.
- requires the admin_forum permission.
*/

// Main handling function for the admin approval center
function RegCenter()
{
global $modSettings$context$txt$scripturl;

// Old templates might still request this.
if (isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'browse')
redirectexit('action=admin;area=viewmembers;sa=browse' . (isset($_REQUEST['type']) ? ';type=' $_REQUEST['type'] : ''));

$subActions = array(
'register' => array('AdminRegister''moderate_forum'),
'agreement' => array('EditAgreement''admin_forum'),
'reservednames' => array('SetReserve''admin_forum'),
'settings' => array('ModifyRegistrationSettings''admin_forum'),
);

// Work out which to call...
$context['sub_action'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (allowedTo('moderate_forum') ? 'register' 'settings');

// Must have sufficient permissions.
isAllowedTo($subActions[$context['sub_action']][1]);

// Loading, always loading.
loadLanguage('Login');
loadTemplate('Register');

// Next create the tabs for the template.
$context[$context['admin_menu_name']]['tab_data'] = array(
'title' => $txt['registration_center'],
'help' => 'registrations',
'description' => $txt['admin_settings_desc'],
'tabs' => array(
'register' => array(
'description' => $txt['admin_register_desc'],
),
'agreement' => array(
'description' => $txt['registration_agreement_desc'],
),
'reservednames' => array(
'description' => $txt['admin_reserved_desc'],
),
'settings' => array(
'description' => $txt['admin_settings_desc'],
)
)
);

// Finally, get around to calling the function...
$subActions[$context['sub_action']][0]();
}

// Quick hack to import a list of users read from a file into the forum database
// with the following characteristics:
// csv file must contain username, firstname, lastname, email address
// and exist along with the files in Sources
//  The user's display name will be their first and lastname
//  A random password will be emailed to the user
//  The user will not be a member of any group
//  The user must activate their account
// Usage: (requires access to your SMF files on your hosting account)
// 1) Create a csv file named members.csv with the new members to add.
// 2) Rename the original ManageRegistration.php to save it.
// 3) Put the members.csv and this file into the Sources folder of your SMF.
// 4) Login as SMF administrator and go to Admin=> Features & Options.
// 5) On the Features & Options menu go to Members=> Registration=> Register New Member
// 6) Click the Register button (no need to fill in form) to import the new members.
// 7) Delete or rename this file and restore the original after confirming the new
//    members have been added.
function AdminRegister()
{
global $txt$context$sourcedir$scripturl$smcFunc;

if (! empty($_POST['regSubmit']))
{
$bad $good 0;
checkSession();

// Read each member to be registered from the text file...
require_once($sourcedir '/Subs-Members.php');
$handle fopen($sourcedir "/members.csv""r");
if ($handle) {
while (($data fgetcsv($handle1000",")) !== FALSE) {
$regOptions = array (
'interface' => 'admin',
'username' => $data[0],
'email' => $data[3],
'password' => '',
'password_check' => '',
'check_reserved_name' => true,
'check_password_strength' => false,
'check_email_ban' => false,
'send_welcome_email' => true,
'require' => 'activation',
'memberGroup' => 0,
);
$memberID registerMember($regOptions);
if (empty($memberID)) ++$bad;
// Now that we have a memberID, update the member name
else {
++$good;
$smcFunc['db_query']('''
   UPDATE {db_prefix}members SET real_name = {string:name}
   WHERE id_member = {int:mem_id}'
,
  
array(
  
  'mem_id' => $memberID,
  
  'name' => $data[1] . " " $data[2],
 
)
);
}
}
echo "<p> Registered $good new members from $sourcedir/members.csv file with $bad errors.</p>\n";
} else {
echo "<p> Problem opening $sourcedir/members.csv file</p>\n";
return;
}
fclose($handle);
}

// Basic stuff.
$context['sub_template'] = 'admin_register';
$context['page_title'] = $txt['registration_center'];
}

// I hereby agree not to be a lazy bum.
function EditAgreement()
{
global $txt$boarddir$context$modSettings$smcFunc$settings;

// By default we look at agreement.txt.
$context['current_agreement'] = '';

// Is there more than one to edit?
$context['editable_agreements'] = array(
'' => $txt['admin_agreement_default'],
);

// Get our languages.
getLanguages();

// Try to figure out if we have more agreements.
foreach ($context['languages'] as $lang)
{
if (file_exists($boarddir '/agreement.' $lang['filename'] . '.txt'))
{
$context['editable_agreements']['.' $lang['filename']] = $lang['name'];
// Are we editing this?
if (isset($_POST['agree_lang']) && $_POST['agree_lang'] == '.' $lang['filename'])
$context['current_agreement'] = '.' $lang['filename'];
}
}

if (isset($_POST['agreement']))
{
checkSession();

// Off it goes to the agreement file.
$fp fopen($boarddir '/agreement' $context['current_agreement'] . '.txt''w');
fwrite($fpstr_replace("\r"''$_POST['agreement']));
fclose($fp);

updateSettings(array('requireAgreement' => !empty($_POST['requireAgreement'])));
}

$context['agreement'] = file_exists($boarddir '/agreement' $context['current_agreement'] . '.txt') ? htmlspecialchars(file_get_contents($boarddir '/agreement' $context['current_agreement'] . '.txt')) : '';
$context['warning'] = is_writable($boarddir '/agreement' $context['current_agreement'] . '.txt') ? '' $txt['agreement_not_writable'];
$context['require_agreement'] = !empty($modSettings['requireAgreement']);

$context['sub_template'] = 'edit_agreement';
$context['page_title'] = $txt['registration_agreement'];
}

// Set reserved names/words....
function SetReserve()
{
global $txt$context$modSettings;

// Submitting new reserved words.
if (!empty($_POST['save_reserved_names']))
{
checkSession();

// Set all the options....
updateSettings(array(
'reserveWord' => (isset($_POST['matchword']) ? '1' '0'),
'reserveCase' => (isset($_POST['matchcase']) ? '1' '0'),
'reserveUser' => (isset($_POST['matchuser']) ? '1' '0'),
'reserveName' => (isset($_POST['matchname']) ? '1' '0'),
'reserveNames' => str_replace("\r"''$_POST['reserved'])
));
}

// Get the reserved word options and words.
$modSettings['reserveNames'] = str_replace('\n'"\n"$modSettings['reserveNames']);
$context['reserved_words'] = explode("\n"$modSettings['reserveNames']);
$context['reserved_word_options'] = array();
$context['reserved_word_options']['match_word'] = $modSettings['reserveWord'] == '1';
$context['reserved_word_options']['match_case'] = $modSettings['reserveCase'] == '1';
$context['reserved_word_options']['match_user'] = $modSettings['reserveUser'] == '1';
$context['reserved_word_options']['match_name'] = $modSettings['reserveName'] == '1';

// Ready the template......
$context['sub_template'] = 'edit_reserved_words';
$context['page_title'] = $txt['admin_reserved_set'];
}

// This function handles registration settings, and provides a few pretty stats too while it's at it.
function ModifyRegistrationSettings($return_config false)
{
global $txt$context$scripturl$modSettings$sourcedir;

// This is really quite wanting.
require_once($sourcedir '/ManageServer.php');

$config_vars = array(
array('select''registration_method', array($txt['setting_registration_standard'], $txt['setting_registration_activate'], $txt['setting_registration_approval'], $txt['setting_registration_disabled'])),
array('check''enableOpenID'),
array('check''notify_new_registration'),
array('check''send_welcomeEmail'),
'',
array('int''coppaAge''subtext' => $txt['setting_coppaAge_desc'], 'onchange' => 'checkCoppa();'),
array('select''coppaType', array($txt['setting_coppaType_reject'], $txt['setting_coppaType_approval']), 'onchange' => 'checkCoppa();'),
array('large_text''coppaPost''subtext' => $txt['setting_coppaPost_desc']),
array('text''coppaFax'),
array('text''coppaPhone'),
);

if ($return_config)
return $config_vars;

// Setup the template
$context['sub_template'] = 'show_settings';
$context['page_title'] = $txt['registration_center'];

if (isset($_GET['save']))
{
checkSession();

// Are there some contacts missing?
if (!empty($_POST['coppaAge']) && !empty($_POST['coppaType']) && empty($_POST['coppaPost']) && empty($_POST['coppaFax']))
fatal_lang_error('admin_setting_coppa_require_contact');

// Post needs to take into account line breaks.
$_POST['coppaPost'] = str_replace("\n"'<br />', empty($_POST['coppaPost']) ? '' $_POST['coppaPost']);

saveDBSettings($config_vars);

redirectexit('action=admin;area=regcenter;sa=settings');
}

$context['post_url'] = $scripturl '?action=admin;area=regcenter;save;sa=settings';
$context['settings_title'] = $txt['settings'];

// Define some javascript for COPPA.
$context['settings_post_javascript'] = '
function checkCoppa()
{
var coppaDisabled = document.getElementById(\'coppaAge\').value == 0;
document.getElementById(\'coppaType\').disabled = coppaDisabled;

var disableContacts = coppaDisabled || document.getElementById(\'coppaType\').options[document.getElementById(\'coppaType\').selectedIndex].value != 1;
document.getElementById(\'coppaPost\').disabled = disableContacts;
document.getElementById(\'coppaFax\').disabled = disableContacts;
document.getElementById(\'coppaPhone\').disabled = disableContacts;
}
checkCoppa();'
;

// Turn the postal address into something suitable for a textbox.
$modSettings['coppaPost'] = !empty($modSettings['coppaPost']) ? preg_replace('~<br ?/?' '>~'"\n"$modSettings['coppaPost']) : '';

prepareDBSettingContext($config_vars);
}
?>


gigashiga

hey this si the code which used to work with earlier version
I guess we need to modify database commands only in it please check if this helps you.

<?php
//Open the template
$csv fopen("members.csv""r") or die("CSV file members.csv could not be found");

$csvdata = array();

while ((
$temp fgetcsv($csv1000",")) !== FALSE) {
    
$csvdata[] = $temp;

}
unset(
$temp);

//Include SSI.php
require("SSI.php");

//include Subs-Members.php
require("Sources/Subs-Members.php");

foreach(
$csvdata as $key)
{
echo 'Importing user: '$key[0] ,'...</br>';
//This array is shamelessly copied from ManageRegistration.php =D
$regOptions = array(
'interface' => 'csvimport',
'username' => $key[0],
'email' => $key[2],
'password' => $key[1],
'password_check' => $key[1],
'check_reserved_name' => true,
'check_password_strength' => false,
'check_email_ban' => false,
'send_welcome_email' => false,
'require' => 'nothing',
'memberGroup' => 0,
);
$memberID registermember($regOptions);
if(!empty($memberID))
{
echo 'Done. <a href=index.php?action=profile;u='$memberID ,'>Member Profile</a><br />';
}
else
die("Error importing member");
}


echo 
'Import complete';
?>

gigashiga


margarett

What kind of update are you waiting for? That code should work, as long as the CSV file is correctly ordered.
Se forem conduzir, não bebam. Se forem beber... CHAMEM-ME!!!! :D

QuoteOver 90% of all computer problems can be traced back to the interface between the keyboard and the chair

gigashiga

this code is not working with 2.07 smf.

margarett

You should update to 2.0.9 ;)

Maybe you can try the tip in the post before your?
Se forem conduzir, não bebam. Se forem beber... CHAMEM-ME!!!! :D

QuoteOver 90% of all computer problems can be traced back to the interface between the keyboard and the chair

Steve

DO NOT pm me for support!

Advertisement: