Posted by butler360 on August 2, 2009 at 1:32am
Jump to:
| Project: | Email Field |
| Version: | 6.x-1.x-dev |
| Component: | Code |
| Category: | support request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Issue Summary
If I enter, say, "user@gmail" for the email address it passes through as-is when, I assume, it should be flagged as invalid.
I feel like I'm missing something because the module is so simple but I don't see any options, really. And I know the module is working because it created a new mailto link on the address.
Comments
#1
that could be valid email address... root@localhost would end up in admin's inbox on most unit machines.
#2
Ah, I see. Is there any way to force the module to not allow that? We've had a few users enter something like I mentioned above, "user@gmail" and while usually it's apparent what they mean (such as with gmail) other times it's not. I never have any use for root@localhost anyways.
#3
+1 on more validation options
the root@localhost example seems to be a rather extreme exception to me .. but it would certainly be nice to be able to configure for that if needed
it seems that in the vast majority of cases being able to validate on an email address with a valid external email address is what is desired
#4
Hey guys - sorry I don't have time to roll this in a patch - but there is an easy answer - The email case 'validate' (in the email field module) uses drupal's core email validation function (which we don't want to use in this case) - so I modified it like this:
<?php
function email_field($op, &$node, $field, &$items, $teaser, $page) {
switch ($op) {
case 'validate':
if (is_array($items)) {
foreach ($items as $delta => $item) {
$validator = new EmailAddressValidator;
if ($validator->check_email_address(trim($item['email']))) {
$email_valid = TRUE;
}
if ($item['email'] != '' && !$email_valid) {
form_set_error($field['field_name'],t('"%mail" is not a valid email address',array('%mail' => $item['email'])));
}
}
}
break;
case 'sanitize':
foreach ($items as $delta => $item) {
$items[$delta]['safe'] = check_plain($item['email']);
}
break;
}
}
?>
and then pasted in google-code email validation located here at the end of the email module:
http://code.google.com/p/php-email-address-validation/source/browse/trun...
code is pasted here for reference:
<?php
/*
EmailAddressValidator Class
<a href="http://code.google.com/p/php-email-address-validation/
" title="http://code.google.com/p/php-email-address-validation/
" rel="nofollow">http://code.google.com/p/php-email-address-validation/
</a> Released under New BSD license
<a href="http://www.opensource.org/licenses/bsd-license.php
" title="http://www.opensource.org/licenses/bsd-license.php
" rel="nofollow">http://www.opensource.org/licenses/bsd-license.php
</a>
Sample Code
----------------
$validator = new EmailAddressValidator;
if ($validator->check_email_address('test@example.org')) {
// Email address is technically valid
}
*/
class EmailAddressValidator {
/**
* Check email address validity
* @param strEmailAddress Email address to be checked
* @return True if email is valid, false if not
*/
public function check_email_address($strEmailAddress) {
// If magic quotes is "on", email addresses with quote marks will
// fail validation because of added escape characters. Uncommenting
// the next three lines will allow for this issue.
//if (get_magic_quotes_gpc()) {
// $strEmailAddress = stripslashes($strEmailAddress);
//}
// Control characters are not allowed
if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $strEmailAddress)) {
return false;
}
// Check email length - min 3 (a@a), max 256
if (!$this->check_text_length($strEmailAddress, 3, 256)) {
return false;
}
// Split it into sections using last instance of "@"
$intAtSymbol = strrpos($strEmailAddress, '@');
if ($intAtSymbol === false) {
// No "@" symbol in email.
return false;
}
$arrEmailAddress[0] = substr($strEmailAddress, 0, $intAtSymbol);
$arrEmailAddress[1] = substr($strEmailAddress, $intAtSymbol + 1);
// Count the "@" symbols. Only one is allowed, except where
// contained in quote marks in the local part. Quickest way to
// check this is to remove anything in quotes. We also remove
// characters escaped with backslash, and the backslash
// character.
$arrTempAddress[0] = preg_replace('/\./'
,''
,$arrEmailAddress[0]);
$arrTempAddress[0] = preg_replace('/"[^"]+"/'
,''
,$arrTempAddress[0]);
$arrTempAddress[1] = $arrEmailAddress[1];
$strTempAddress = $arrTempAddress[0] . $arrTempAddress[1];
// Then check - should be no "@" symbols.
if (strrpos($strTempAddress, '@') !== false) {
// "@" symbol found
return false;
}
// Check local portion
if (!$this->check_local_portion($arrEmailAddress[0])) {
return false;
}
// Check domain portion
if (!$this->check_domain_portion($arrEmailAddress[1])) {
return false;
}
// If we're still here, all checks above passed. Email is valid.
return true;
}
/**
* Checks email section before "@" symbol for validity
* @param strLocalPortion Text to be checked
* @return True if local portion is valid, false if not
*/
protected function check_local_portion($strLocalPortion) {
// Local portion can only be from 1 to 64 characters, inclusive.
// Please note that servers are encouraged to accept longer local
// parts than 64 characters.
if (!$this->check_text_length($strLocalPortion, 1, 64)) {
return false;
}
// Local portion must be:
// 1) a dot-atom (strings separated by periods)
// 2) a quoted string
// 3) an obsolete format string (combination of the above)
$arrLocalPortion = explode('.', $strLocalPortion);
for ($i = 0, $max = sizeof($arrLocalPortion); $i < $max; $i++) {
if (!preg_match('.^('
. '([A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]'
. '[A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]{0,63})'
.'|'
. '("[^\\\"]{0,62}")'
.')$.'
,$arrLocalPortion[$i])) {
return false;
}
}
return true;
}
/**
* Checks email section after "@" symbol for validity
* @param strDomainPortion Text to be checked
* @return True if domain portion is valid, false if not
*/
protected function check_domain_portion($strDomainPortion) {
// Total domain can only be from 1 to 255 characters, inclusive
if (!$this->check_text_length($strDomainPortion, 1, 255)) {
return false;
}
// Check if domain is IP, possibly enclosed in square brackets.
if (preg_match('/^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
.'(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}$/'
,$strDomainPortion) ||
preg_match('/^\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
.'(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\]$/'
,$strDomainPortion)) {
return true;
} else {
$arrDomainPortion = explode('.', $strDomainPortion);
if (sizeof($arrDomainPortion) < 2) {
return false; // Not enough parts to domain
}
for ($i = 0, $max = sizeof($arrDomainPortion); $i < $max; $i++) {
// Each portion must be between 1 and 63 characters, inclusive
if (!$this->check_text_length($arrDomainPortion[$i], 1, 63)) {
return false;
}
if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|'
.'([A-Za-z0-9]+))$/', $arrDomainPortion[$i])) {
return false;
}
if ($i == $max - 1) { // TLD cannot be only numbers
if (strlen(preg_replace('/[0-9]/', '', $arrDomainPortion[$i])) <= 0) {
return false;
}
}
}
}
return true;
}
/**
* Check given text length is between defined bounds
* @param strText Text to be checked
* @param intMinimum Minimum acceptable length
* @param intMaximum Maximum acceptable length
* @return True if string is within bounds (inclusive), false if not
*/
protected function check_text_length($strText, $intMinimum, $intMaximum) {
// Minimum and maximum are both inclusive
$intTextLength = strlen($strText);
if (($intTextLength < $intMinimum) || ($intTextLength > $intMaximum)) {
return false;
} else {
return true;
}
}
}
?>
#5
You probably want to do something like this:
http://www.webdigi.co.uk/blog/2009/how-to-check-if-an-email-address-exis...
The fact that the address is syntactically correct does not prove that it exists.
cheers
#6
This is perfect, just what I was searching for, #4 worked.
It would great at one point to see a UI setting to allow only emails with an actual domain attached. I agree with the above, "email@localhost" is an extreme case.
#7
I agree that because email@localhost is the exception it should be dealt with like any other exception in validation (as in validate this pattern as OK).
#8
This module reportedly uses the technique from the link in #5
http://drupal.org/project/email_verify
#9
Well, there's two different validations. One is for whether the email address really exists. The other (which I what I was looking for) is just to make sure the person doesn't make a dumb mistake, like "user@gmail."
And while root@localhost may be a valid email address, how often is that address going to be put into a form? I agree that an option in the interface would be best.