Importing WordPress users is not as challenging as importing WooCommerce variable products or even just products. But there are a few issues that, if ignored, can cause you considerable grief.
In this article, we're going to take a look at how WP All Import handles user imports in general and these potential problem issues in particular.
Sometimes, you will receive an import file that includes users that you don't want to import. A classic example of this is where the file includes an admin from another system that you don't want to import as an admin into your system.
Fortunately, WP All Import has a very intuitive filter system that lets you quickly create a filter to address this:
You aren't limited to just one rule, either. You can add as many rules as you want, separating each rule with an AND or OR condition:
In this filter, you're asking for users who are customers but not admins.
You can even group or nest filter conditions by indenting them, which is the same as using parentheses:
Here, you're asking to import users where:
username(1) <> "admin" AND (userrole(1) equals "customer" OR userrole(1) = "subscriber")
This nesting or grouping ability is unique to WP All Import and allows you to create any filter you want.
One of the great appeals of WP All Import is that it provides a slick Drag & Drop interface that allows you to map incoming data elements to WordPress user fields simply by dragging and dropping them into place:
As you can see in the red box on the lower half of the screen, WP All Import organizes user fields into logical sections to help you more easily map related sets of fields.
For the most part, this mapping process is fairly straightforward. But there may be instances where you may need to combine multiple incoming data elements with literal values to get the result you're after:
Here, we've created a Description field that consists of the literal value "Address:" plus a series of fields, each separated by a comma.
However, sometimes, the challenge you're facing isn't just the need to combine multiple data elements into one user field. Sometimes, the incoming data elements are in the wrong format, need to be split apart, or contain values that need to be modified.
If you receive user data from a 3rd-party, it will inevitably contain something that doesn't align or conform to the data requirements of your WordPress user fields.
Unfortunately, many user import plugins treat this issue in one of two ways:
Neither of these solutions is acceptable, especially when WordPress user data is mostly text.
WP All Import takes a completely different approach. It allows you to apply built-in PHP functions to incoming data elements as part of mapping those elements to user fields. For example, here is the PHP str_replace() function being used to strip commas out of a text field:
PHP provides a large number of these functions. For example, here's a list of just the string-related PHP functions copied from W3 Schools:
addcslashes() | Returns a string with backslashes in front of the specified characters |
addslashes() | Returns a string with backslashes in front of predefined characters |
bin2hex() | Converts a string of ASCII characters to hexadecimal values |
chop() | Removes whitespace or other characters from the right end of a string |
chr() | Returns a character from a specified ASCII value |
chunk_split() | Splits a string into a series of smaller parts |
convert_cyr_string() | Converts a string from one Cyrillic character-set to another |
convert_uudecode() | Decodes a uuencoded string |
convert_uuencode() | Encodes a string using the uuencode algorithm |
count_chars() | Returns information about characters used in a string |
crc32() | Calculates a 32-bit CRC for a string |
crypt() | One-way string hashing |
echo() | Outputs one or more strings |
explode() | Breaks a string into an array |
fprintf() | Writes a formatted string to a specified output stream |
get_html_translation_table() | Returns the translation table used by htmlspecialchars() and htmlentities() |
hebrev() | Converts Hebrew text to visual text |
hebrevc() | Converts Hebrew text to visual text and new lines (\n) into <br> |
hex2bin() | Converts a string of hexadecimal values to ASCII characters |
html_entity_decode() | Converts HTML entities to characters |
htmlentities() | Converts characters to HTML entities |
htmlspecialchars_decode() | Converts some predefined HTML entities to characters |
htmlspecialchars() | Converts some predefined characters to HTML entities |
implode() | Returns a string from the elements of an array |
join() | Alias of implode() |
lcfirst() | Converts the first character of a string to lowercase |
levenshtein() | Returns the Levenshtein distance between two strings |
localeconv() | Returns locale numeric and monetary formatting information |
ltrim() | Removes whitespace or other characters from the left side of a string |
md5() | Calculates the MD5 hash of a string |
md5_file() | Calculates the MD5 hash of a file |
metaphone() | Calculates the metaphone key of a string |
money_format() | Returns a string formatted as a currency string |
nl_langinfo() | Returns specific local information |
nl2br() | Inserts HTML line breaks in front of each newline in a string |
number_format() | Formats a number with grouped thousands |
ord() | Returns the ASCII value of the first character of a string |
parse_str() | Parses a query string into variables |
print() | Outputs one or more strings |
printf() | Outputs a formatted string |
quoted_printable_decode() | Converts a quoted-printable string to an 8-bit string |
quoted_printable_encode() | Converts an 8-bit string to a quoted printable string |
quotemeta() | Quotes meta characters |
rtrim() | Removes whitespace or other characters from the right side of a string |
setlocale() | Sets locale information |
sha1() | Calculates the SHA-1 hash of a string |
sha1_file() | Calculates the SHA-1 hash of a file |
similar_text() | Calculates the similarity between two strings |
soundex() | Calculates the soundex key of a string |
sprintf() | Writes a formatted string to a variable |
sscanf() | Parses input from a string according to a format |
str_getcsv() | Parses a CSV string into an array |
str_ireplace() | Replaces some characters in a string (case-insensitive) |
str_pad() | Pads a string to a new length |
str_repeat() | Repeats a string a specified number of times |
str_replace() | Replaces some characters in a string (case-sensitive) |
str_rot13() | Performs the ROT13 encoding on a string |
str_shuffle() | Randomly shuffles all characters in a string |
str_split() | Splits a string into an array |
str_word_count() | Count the number of words in a string |
strcasecmp() | Compares two strings (case-insensitive) |
strchr() | Finds the first occurrence of a string inside another string (alias of strstr()) |
strcmp() | Compares two strings (case-sensitive) |
strcoll() | Compares two strings (locale based string comparison) |
strcspn() | Returns the number of characters found in a string before any part of some specified characters are found |
strip_tags() | Strips HTML and PHP tags from a string |
stripcslashes() | Unquotes a string quoted with addcslashes() |
stripslashes() | Unquotes a string quoted with addslashes() |
stripos() | Returns the position of the first occurrence of a string inside another string (case-insensitive) |
stristr() | Finds the first occurrence of a string inside another string (case-insensitive) |
strlen() | Returns the length of a string |
strnatcasecmp() | Compares two strings using a "natural order" algorithm (case-insensitive) |
strnatcmp() | Compares two strings using a "natural order" algorithm (case-sensitive) |
strncasecmp() | String comparison of the first n characters (case-insensitive) |
strncmp() | String comparison of the first n characters (case-sensitive) |
strpbrk() | Searches a string for any of a set of characters |
strpos() | Returns the position of the first occurrence of a string inside another string (case-sensitive) |
strrchr() | Finds the last occurrence of a string inside another string |
strrev() | Reverses a string |
strripos() | Finds the position of the last occurrence of a string inside another string (case-insensitive) |
strrpos() | Finds the position of the last occurrence of a string inside another string (case-sensitive) |
strspn() | Returns the number of characters found in a string that contains only characters from a specified charlist |
strstr() | Finds the first occurrence of a string inside another string (case-sensitive) |
strtok() | Splits a string into smaller strings |
strtolower() | Converts a string to lowercase letters |
strtoupper() | Converts a string to uppercase letters |
strtr() | Translates certain characters in a string |
substr() | Returns a part of a string |
substr_compare() | Compares two strings from a specified start position (binary safe and optionally case-sensitive) |
substr_count() | Counts the number of times a substring occurs in a string |
substr_replace() | Replaces a part of a string with another string |
trim() | Removes whitespace or other characters from both sides of a string |
ucfirst() | Converts the first character of a string to uppercase |
ucwords() | Converts the first character of each word in a string to uppercase |
vfprintf() | Writes a formatted string to a specified output stream |
vprintf() | Outputs a formatted string |
vsprintf() | Writes a formatted string to a variable |
wordwrap() | Wraps a string to a given number of characters |
There are scores of other functions for other data types, including numeric, date, boolean, array, etc.
Not enough for you? WP All Import also provides an embedded PHP function editor that lets you create your own custom PHP functions:
These functions perform any task you wish, including the use of conditional logic, and they can be used much like you use a built-in PHP function.
This lets you do whatever you need to incoming data elements to make them comply with the requirements of WordPress user fields.
This is another significant advantage that WP All Import has over other import plugins.
WordPress user passwords are stored in the WordPress database in their hashed (i.e., encrypted) form. For security reasons, the original text password is never stored.
When a user logs into WordPress, the password they type into the login form is hashed using the same algorithm, and WordPress then compares the two hashed values to see if they match.
When you receive a user import file, there are three possibilities with respect to user passwords:
In the third instance, you typically want to import the hashed password values as they are, meaning that new users can log into your system using the same passwords they used previously on whatever system is the source of your new users.
WP All Import lets you do this by clicking the following interface option:
What do you do if there are no user passwords in the import data or if there are passwords but they're in plain text?
In both of these cases, the recommended practice is to force newly imported users to reset their passwords by sending them a password reset notification. While it is true that WordPress will automatically hash any plain text passwords in the incoming data, meaning that affected users could use their old passwords to log into your system, this is not recommended because the passwords may have been exposed during the transmission of the import file.
In the introduction to this article, we mentioned that there are some user import issues that can cause you a lot of grief. This is one of them.
When you create a new user in WordPress, the default behavior is to notify the user that they have been added to your system.
This default behavior also applies to new users when they are created during a user import, which can cause headaches for the administrator. For example, something may go wrong during an import, forcing the administrator to roll it back and then import the users again. The last thing you want to do in this scenario is to subject new users to multiple email notifications.
The best practice is instead to block notifications to new users until after the import has successfully completed, at which point you can selectively notify users of their access to your system.
To block notifications, simply select the Block email notifications during import option, as shown below.
When you import WordPress users, they are treated as new users and assigned a new User ID. This is generally okay unless you are importing other data along with the users and there is a link between the two datasets based on the old User ID.
If the other data in question is fully recognized by WP All Import, that won't matter. As long as you import the users first and the other data afterward, WP All Import will likely be able to help you relink the data even if the user gets a new User ID. This is the case, for example, when you import WooCommerce customers, followed by WooCommerce orders, and you need to link them together after the import even though the customer User IDs have changed.
But what if you're importing a custom dataset that isn't fully recognized by WP All Import? Your best bet is to use a bit of custom code to try to preserve the old UserIDs, if possible. You can read about this at Keep Old IDs When Migrating Users or Customers.
This isn't a how-to document, so we're not trying to show you how to do this. Our point in mentioning it is that even when WP All Import hasn't turned an import task into a convenient interface option, they still have a wealth of experience, code samples, etc., to help you tackle sticky issues like this one.
Scheduling WordPress user imports is not as common as scheduling WooCommerce product or order imports, but it can sometimes be necessary. For example, if you run external marketing or recruitment campaigns and you want to import the latest free trial customers from those campaigns.
The process of scheduling a user import is pretty straightforward when using WP All Import's paid Automatic Scheduling Service. Just choose the frequency, day, time, and time zone, and this service will run your user import accordingly. It'll even verify for you that it ran correctly.
If you don't want to pay the $9 monthly fee for the Automatic Scheduling Service, you can still schedule your user import by manually setting up cron jobs on your server:
Either way, WP All Import has you covered.
WP All Import has been serving the data import, export, migration, and bulk editing needs of the WordPress and WooCommerce communities for over a decade. Its main import plugin boasts over 100,000 active installs and 1,800 customer ratings, the vast majority of which are 5-star.
You can see the genuine enthusiasm for this plugin by reading the user reviews yourself at https://wordpress.org/support/plugin/wp-all-import/reviews/.
As we stated at the beginning of this article, importing WordPress users is not the most daunting import task in the WordPress/WooCommerce ecosystem, but there are still a lot of details to address if you want to do it right.
What we like about WP All Import is that it makes most of these details routine simply by providing interface options to address them.
In the rare instances where this isn't the case, you can still draw on WP All Import's experience, sample code, and support team to help you solve whatever problem you're facing.
Import WordPress Users from CSV, Excel, and XML
The 5 Best WordPress User Import Plugins
The 5 Best Plugins for WordPress User Import from CSV
The 5 Best Plugins to Import WordPress Users from Excel