View Single Post
  #1  
Old 11-23-2011, 08:00 AM
 
exsecror exsecror is offline
 

X-Wizard
  
Join Date: Apr 2007
Posts: 1,284
 

Default Improved Email Address Validation

Probably one of the most important aspects of doing business online is the ability to ensure that a customer is kept well informed about the status of their order, whether that status may be that it shipped or it had to be backordered or that a credit card payment (for those that capture payment during shipment and not at time of sale) did not go through.

The issue that can arise however (and we experience this frequently) is the customer will often purposefully provide a fake email address or one with a disposable email service or even by accident provide an email address that is invalid due to typographical errors or the mailbox may be full. In order to combat this issue we re-wrote the func_check_email() procedure that comes with X-Cart to further enhance it's abilities. The reason for this is that the procedure only checks for syntax validity, not existence or validity of the mailbox itself.

MODIFICATION REQUIREMENTS:MODIFICATION RECOMMENDATIONS:
  • PHP filter Extension (if not present, will use X-Cart fallback)
NOTICE:

This modification is provided as-is with no guarantee or warranty. It is intended for advanced users only as patches are not provided and does not include an admin interface. It is assumed that any manual additions to the filter table will be done through a direct SQL console interface such as the MySQL Workbench, phpMyAdmin, PremiumSoft Navicat MySQL or MySQL CLI.

================================================== ======

STEP 1: The Email Validation SQL Table

The first step is to add the SQL table that will be referenced by the functions func_check_email() and func_check_email_towerdata(). This is mainly intended as both a caching assistant and to handle permanently blacklisted usernames and domain names (as well as bad MX records).

Code:
DROP TABLE IF EXISTS `filter_email_validation`; CREATE TABLE `filter_email_validation` ( `filter_value` varchar(255) NOT NULL, `filter_type` enum('D','M','L') NOT NULL, `filter_permanent` tinyint(4) NOT NULL, `filter_expires` int(11) NOT NULL, PRIMARY KEY (`filter_value`) )
The table supports 3 types of records:

L - localpart or username
D - domain name
M - MX record (for people that use bad or fake MX records like mx.fakemx.net)

There's also a field called filter_permanent which denotes 0 (false) or 1 (true) that the filter is a permanent one and should not be purged during frequent checks against the filter_expires field. Once you have that table created proceed to step 2.

================================================== ======

STEP 2: Modification of func_check_email()

Now that we have the SQL table necessary to make this work created, it is time to re-write the func_check_email() function.

Locate the function func_check_email() and replace the entire contents with the following:

include/func/func.mail.php:

PHP Code:
// {{{ func_check_email()
/**
 * This function checks if an email is valid
 * 
 * @param string $email the email address to check
 * @return bool true if valid; false if not
 */
function func_check_email($email) {
    @
db_query('DELETE FROM filter_email_validation WHERE filter_expires < UNIX_TIMESTAMP() AND filter_permanent = 0');
    
    
$email                    trim(strtolower(stripslashes($email)));
    
$filters                  func_query('SELECT filter_type, filter_value FROM filter_email_validation');
    
$email_regular_expression func_email_validation_regexp();

    list(
$localpart$domain) = split('@'$email);
    @
getmxrr($domain$mx_results);
    
    if (
count($mx_results) === 0) {
        return 
false;
    }
     
    if (
extension_loaded('filter')) {
        if (!
filter_var(filter_var($emailFILTER_SANITIZE_EMAIL), FILTER_VALIDATE_EMAIL)) {
            return 
false;
        }
    }
    else {
        if (!
preg_match('/' $email_regular_expression '/Di'$email)) {
            return 
false;
        }
    }
    
    foreach (
$filters as $filter) {
        switch (
$filter['filter_type']) {
            case 
'D':
                if (
$domain === $filter['filter_value']) {
                    return 
false;
                }
                break;
            case 
'L':
                if (
$localpart === $filter['filter_value']) {
                    return 
false;
                } 
                break;
            case 
'M':
                if (
array_search($filter['filter_value'], $mx_results) !== false) {
                    return 
false;
                }
                break;
            default:
                break;
        }
    }
    
    if (!
func_check_email_towerdata($email)) {
        return 
false;
    }
    
    return 
true;
}
// }}} 
As you can see this is a much more extension function than the original on provided. It checks for the existence of MX records, runs through the filter_email_validation table to ensure nothing matches and then will make an external call to the TowerData validation service via another function (which will be provided in Step 3). Once you have completely re-written the function, proceed to Step 3.
Reply With Quote