Avoid wrong email adresses and log these to dblog

Last updated on
30 April 2025

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:

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

Page status: Not set

You can: