Avoid wrong email adresses and log these to dblog
This Cookbook shows, how you can avoid to import a user in case of errors in the e-mail address and then to add a notice in the drupal error-log (dblog). It adds this behavior to the module A Wusel Migration (http://drupal.org/node/1285276).
Cookbook:
Step 1: Enable database logging
If the module database logging is not enabled, then enable it on the Extend page at 'http://example.com/admin/modules'!
Step 2: Add the code
Open the existing file "sites/all/modules/a_wusel_migration/a_wusel_migration.migrate.inc" and insert at the top of the file after the first comment the new lines [1]:
/**
* Email address validation with domain name
* and log all errors at dblog (watchdog)
*
* returns TRUE on success and FALSE on failure
*
* based on: drupal.org/node/755894
*/
function email_validate($email, $name, $migration) {
$isValid = true;
$atIndex = strrpos($email, "@");
if(is_bool($atIndex) && !$atIndex) {
// empty email field
$isValid = false;
}
else {
$domain = substr($email, $atIndex+1);
$local = substr($email, 0, $atIndex);
$localLen = strlen($local);
$domainLen = strlen($domain);
if($localLen < 1 || $localLen > 64) {
// local part length exceeded
$isValid = false;
} else if($domainLen < 1 || $domainLen > 255) {
// domain part length exceeded
$isValid = false;
} else if($local[0] == '.' || $local[$localLen-1] == '.') {
// local part starts or ends with '.'
$isValid = false;
} else if(preg_match('/\\.\\./', $local)) {
// local part has two consecutive dots
$isValid = false;
} else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) {
// character not valid in domain part
$isValid = false;
} else if(preg_match('/\\.\\./', $domain)) {
// domain part has two consecutive dots
$isValid = false;
} else if(!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\","",$local))) {
// character not valid in local part unless
// local part is quoted
if (!preg_match('/^"(\\"|[^"])+"$/', str_replace("\\","",$local))) {
$isValid = false;
}
}
if($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A"))) {
// domain not found in DNS
$isValid = false;
}
}
if (!$isValid) {
// api.drupal.org/api/drupal/includes!bootstrap.inc/function/watchdog/7
watchdog($migration, t('User @name has no correct email @mail and is ignored'), $variables = array('@name' => '"' . $name . '"', '@mail' => '("' . $email . '")'), $severity = WATCHDOG_NOTICE);
}
return $isValid;
}
Then add the follwing lines in front of the closing curly bracket of the class Wusel_Step1_UserMigration [1]:
/**
* based on: drupal.org/node/1132582
*/
public function prepareRow($row) {
// Always include this fragment at the beginning of every prepareRow()
// implementation, so parent classes can ignore rows.
if (parent::prepareRow($row) === FALSE) {
return FALSE;
}
// The argument $row is a stdClass object containing the raw data as provided by the source.
//
// If there is an error in mail in the related data, skip this row
if (!email_validate($row->mail, $row->name, 'Wusel_Step1_UserMigration')) {
return FALSE; // skip this row (by returning FALSE)
}
return TRUE;
}
Then add the follwing lines in front of the closing curly bracket of the class Wusel_Step2_MemberlistMigration [1]:
/**
* based on: drupal.org/node/1132582
*/
public function prepareRow($row) {
// Always include this fragment at the beginning of every prepareRow()
// implementation, so parent classes can ignore rows.
if (parent::prepareRow($row) === FALSE) {
return FALSE;
}
// The argument $row is a stdClass object containing the raw data as provided by the source.
//
// If there is an error in mail in the related data, skip this row
if (!email_validate($row->mail, $row->name, 'Wusel_Step2_MemberlistMigration')) {
return FALSE; // skip this row (by returning FALSE)
}
return TRUE;
}
Save this file.
Step 3: Prepare the CSV file
Open the existing file "sites/all/modules/a_wusel_migration/data_sources/drupaluser_import.csv" and change its content to[2]:
"member_nr","email","username","password","complete_name","birthday","tel_1"
"1001","new.tester@example.com","new tester","test","New Tester","07/13/1999","00000 12345-213"
"1002","old.tester@example.com","old tester","test","Old Tester","12.07.1945","00000/54321-0"
"1003","another.tester@example.com","another tester","test","Another Tester","1985-07-11","00000 678901"
"1004","","incognito user","test","Incognito User","",""
"2001","foo@example.com","foo","test","Foo","23.05.2013","+49 98765 987654-321"
"2002","wrong..email1@example.com","wrong email","test","Wrong..Email1","28.06.1954",""
"2003","wrong.email2@examplecom","wrong email2","test","Wrong Email2","28.06.1924",""
"2004","x.y.user@example.net","x y user","test","X. Y. User","28.06.2004",""
Save this file.
Step 4: Import
Clear your cache, e.g. at 'http://example.com/admin/config/development/performance'.
There are two alternatives for the rest of this step:
a) Import with Drush (recommended)
step 1 to create the user accounts:
drush mi Wusel_Step1_User
step 2 to create the profiles:
drush mi Wusel_Step2_Memberlist
Hint: get a list of the registered Class Names with drush ms. If you named the Migration Class "Wusel_Step1_UserMigration" the class name will be "Wusel_Step1_User" (without "Migration").
Or:
b) Import with the Migrate UI via the web admin
If you have enabled the module migrate_ui:
Go to Administration > Content > Migrate and click on "WuselMigrate Imports" or go to http://example.com/admin/content/migrate/groups/WuselMigrate.
Check the box for the first migration Wusel_Step1_User, select "Import" or "Import immediately" and click on "Execute".
Check the box for the second migration Wusel_Step2_Memberlist, select "Import" or "Import immediately" and click on "Execute".
Step 5: Show the import
Visit 'http://example.com/admin/people'.
You have imported five users, if you have changed nothing in the CSV file and this was the first import.
Step 6: Show the error-log
Visit 'http://example.com/admin/reports/dblog'.
You will see three messages for every of the two migrations, if you have changed nothing in the CSV file and this was the first import.
Note:
[1]: Don't include the "<?php" and "?>" from above to the file! Here it is only visible to format this page-text.
Good luck!
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion