We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 49499
    • 48 Posts
    I'm looking for the best way to bulk import over 5,000 users from a Wordpress site to MODx. Unfortunately, I don't believe there's a way to decrypt Wordpress's salt+MD5 encryption, so users will need their passwords reset.

    That being said, I need three things:

    1. Import all users
    2. Reset all passwords
    3. Send everyone an email with account login details

    Does anyone have any suggestions? I would greatly appreciate any help or guidance!
      • 28042 ☆ A M B ☆
      • 24,524 Posts
      I presume you have exported your WP users into a file that can be parsed and the username and email and full name extracted for MODX to use while creating the new users.

      One option would be to go ahead and create the users with the new password, and change the "login failed" message (in core/lexicon/en/login.inc.php around line 32) to notify them that due to system updates, they need to change their password, along with a link to your change password page. This would avoid the sending of all those emails, and I can guarantee you that a goodly percentage of your users are going to forget, not even notice the email, or for whatever reason be trying to log in with the old password anyway.

      Another option would be to use runProcessor when creating the new users - scroll down to the last example "You can also create an entire user, including Extended Fields, group assignments, a generated password and email notification." http://rtfm.modx.com/revolution/2.x/developing-in-modx/advanced-development/using-runprocessor

      Using the latter method you would definitely need to break your exported WP user file into small segments so you aren't sending 5,000 emails at once!
        Studying MODX in the desert - http://sottwell.com
        Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
        Join the Slack Community - http://modx.org
        • 5430
        • 247 Posts
        Get your users out of WordPress as a csv file (this might work https://wordpress.org/plugins/export-users-to-csv/)

        post the CSV on the server where MODX is installed and then you can run a snippet like the following to do the import:

        <?php
        
        $file = "path/to/your.csv";
        
        // Setup variables for logging
        $iAddCount = 0;
        $iChangeCount = 0;
        $addLog = '';
        $sChangeLog = '';
        
        //open and process the csv
        if (($csv = fopen($file,'r')) != FALSE) {
        
        	$modx->setLogLevel(modX::LOG_LEVEL_INFO);
        	$modx->setLogTarget('ECHO');
        
        	// loop through each line of the csv and capture the data into variables.
        	// Set your own variables based on the ordering and content of the csv.
        	// This is also where you set the separator character, in this case a comma, but it may not be in your file
        	while(($data = fgetcsv($csv, 1000, ",", '"')) !== FALSE)
        	{
        		$username	= $data[0];
        		$fullname	= $data[1];
        		$email		= $data[2];
        		$fullname	= $data[3];
        		$address	= $data[4];
        		$city		= $data[5];
        		$state		= $data[6];
        		$zip		= $data[7];
        		$country	= $data[8];
        
        		// create an array to store essential user data
        		$uFields = array(
        			'username' 	=> $dNumber,
        			'email' 	=> $dNumber,
        			//simple hash of email address as temporary password, you could insert whatever you like instead of a hash
        			'password' 	=> sha1($email),
        			'active'   	=> 1,
        			'blocked'  	=> 0,
        		);
        		
        		// create an array to store user profile data (stored in a different table in the db)
        		$pFields = array(
        			'email' 	=> $email,
        			'fullname' 	=> $fullname,
        			'address' 	=> $address,
        			'city' 		=> $city,
        			'state' 	=> $state,
        			'zip' 		=> $zip,
        			'country' 	=> $country,
        		);
        
        		// create the user.
        		$user  = $modx->newObject('modUser', $uFields);
        		$profile = $modx->newObject('modUserProfile', $pFields);	
        		$success = $user->addOne($profile);
        		
        		if ($success) 
        		{
        			$addLog .= $profile->get('fullname'). ' added'.PHP_EOL;
        			$iAddCount++;
        			$user->save();
        			//!!super important, be sure to assign this user to a usergroup (first digit is usergroup id #) and a role (second digit is role id)
        			$user->joinGroup(4,1);
        		} 
        		else 
        		{
        			$modx->log(modX::LOG_LEVEL_INFO,'Failed to add '.$dFirstName.' '.$dLastName. PHP_EOL);
        		}
        	}
        
        	$logDate = date('l jS \of F Y h:i:s A').PHP_EOL;
        	$logAll = 'Users added: '.$iAddCount . PHP_EOL . 'Users updated: '.$iChangeCount.PHP_EOL;
        	$log = fopen('assets/import/log.txt','w+');
        	fwrite($log, $logDate);
        	fwrite($log, $logAll);
        	fwrite($log, $addLog);
        	fclose($log);
        	
        	$modx->log(modX::LOG_LEVEL_INFO,'End of import'. PHP_EOL . 'Users added: '.$iAddCount . PHP_EOL . 'Users updated: '.$iChangeCount. PHP_EOL);
        
        }


        After their imported you can use something like Notify (http://bobsguides.com/notify-tutorial.html) to send your email.
          • 5430
          • 247 Posts
          Oops, just noticed carryover syntax from my version of this snippet. Replace lines 34 and 35 with
          'username' 	=> $username,
          			'email' 	=> $email,
            • 3749
            • 24,544 Posts
            I'll probably be sorry I mentioned this, but it's possible to create a login form that asks for username, password, and email. You use the user's email address to validate them, and then save the password they enter when logging in as their permanent password. This assumes that you've imported them into the MODX DB (and the WP database includes their email addresses) -- *and* you've made sure the salt field is empty in the MODX DB *and* you've set the hash_class field for all users to hashing.modPBKDF2. You'll also need to be sure each user has a profile, but that should happen during the import.

            This is all transparent to the users as long as they enter the correct username, password, and email. You just have to tell them to be sure they use the same email address WP has because it will be part of the initial authentication.

            You'd attach a plugin with code like this (untested) to OnManagerAuthentication and/or OnWebAuthentication:

            $givenPassword = $password;
            $givenEmail = $_POST['email'];
            $username = $user->get('username');
            $authenticated = false;
            $salt = $user->get('salt');
            
            /* I think this will work: */
            $email = $user->Profile->get('email');
            
            /* If not:
            
            $profile = $user->getOne('Profile');
            if ($profile) {
                $email = $profile->get('email');
            }
            
            */
            
            /* Checking the salt bypasses this all once they're properly registered */
            if (empty($salt)) {
                if ( (!empty ($givenEmail)) && (!empty($email)) ) {
                    if ($givenEmail === $email) {
                        $authenticated = true;
                        $user->set('password', $givenPassword);
                        $user->save();
                    }
                }
            }
            
            $modx->event->_output = (bool) $authenticated;
            return '';


            BTW, if you need a more secure solution and you don't mind spelunking in the WordPress code, you can find the WP hashing algorithm and use it rather than the email to do the initial authentication.

            [ed. note: BobRay last edited this post 11 years, 3 months ago.]
              Did I help you? Buy me a beer
              Get my Book: MODX:The Official Guide
              MODX info for everyone: http://bobsguides.com/modx.html
              My MODX Extras
              Bob's Guides is now hosted at A2 MODX Hosting