|
|
@@ -41,6 +41,7 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
const INVALID_FORMAT = 'emailAddressInvalidFormat';
|
|
|
const INVALID_HOSTNAME = 'emailAddressInvalidHostname';
|
|
|
const INVALID_MX_RECORD = 'emailAddressInvalidMxRecord';
|
|
|
+ const INVALID_SEGMENT = 'emailAddressInvalidSegment';
|
|
|
const DOT_ATOM = 'emailAddressDotAtom';
|
|
|
const QUOTED_STRING = 'emailAddressQuotedString';
|
|
|
const INVALID_LOCAL_PART = 'emailAddressInvalidLocalPart';
|
|
|
@@ -54,6 +55,7 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
self::INVALID_FORMAT => "'%value%' is not a valid email address in the basic format local-part@hostname",
|
|
|
self::INVALID_HOSTNAME => "'%hostname%' is not a valid hostname for email address '%value%'",
|
|
|
self::INVALID_MX_RECORD => "'%hostname%' does not appear to have a valid MX record for the email address '%value%'",
|
|
|
+ self::INVALID_SEGMENT => "'%hostname%' is not in a routable network segment. The email address '%value%' should not be resolved from public network.",
|
|
|
self::DOT_ATOM => "'%localPart%' not matched against dot-atom format",
|
|
|
self::QUOTED_STRING => "'%localPart%' not matched against quoted-string format",
|
|
|
self::INVALID_LOCAL_PART => "'%localPart%' is not a valid local part for email address '%value%'",
|
|
|
@@ -61,27 +63,36 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
);
|
|
|
|
|
|
/**
|
|
|
+ * @see http://en.wikipedia.org/wiki/IPv4
|
|
|
* @var array
|
|
|
*/
|
|
|
- protected $_messageVariables = array(
|
|
|
- 'hostname' => '_hostname',
|
|
|
- 'localPart' => '_localPart'
|
|
|
+ protected $_invalidIp = array(
|
|
|
+ '0' => '0.0.0.0/8',
|
|
|
+ '10' => '10.0.0.0/8',
|
|
|
+ '127' => '127.0.0.0/8',
|
|
|
+ '128' => '128.0.0.0/16',
|
|
|
+ '169' => '169.254.0.0/16',
|
|
|
+ '172' => '172.16.0.0/12',
|
|
|
+ '191' => '191.255.0.0/16',
|
|
|
+ '192' => array(
|
|
|
+ '192.0.0.0/24',
|
|
|
+ '192.0.2.0/24',
|
|
|
+ '192.88.99.0/24',
|
|
|
+ '192.168.0.0/16'
|
|
|
+ ),
|
|
|
+ '198' => '198.18.0.0/15',
|
|
|
+ '223' => '223.255.255.0/24',
|
|
|
+ '224' => '224.0.0.0/4',
|
|
|
+ '240' => '240.0.0.0/4'
|
|
|
);
|
|
|
|
|
|
/**
|
|
|
- * Local object for validating the hostname part of an email address
|
|
|
- *
|
|
|
- * @var Zend_Validate_Hostname
|
|
|
- * @depreciated
|
|
|
- */
|
|
|
- public $hostnameValidator;
|
|
|
-
|
|
|
- /**
|
|
|
- * Whether we check for a valid MX record via DNS
|
|
|
- *
|
|
|
- * @var boolean
|
|
|
+ * @var array
|
|
|
*/
|
|
|
- protected $_validateMx = false;
|
|
|
+ protected $_messageVariables = array(
|
|
|
+ 'hostname' => '_hostname',
|
|
|
+ 'localPart' => '_localPart'
|
|
|
+ );
|
|
|
|
|
|
/**
|
|
|
* @var string
|
|
|
@@ -94,21 +105,99 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
protected $_localPart;
|
|
|
|
|
|
/**
|
|
|
+ * Internal options array
|
|
|
+ */
|
|
|
+ protected $_options = array(
|
|
|
+ 'mx' => false,
|
|
|
+ 'deep' => false,
|
|
|
+ 'domain' => true,
|
|
|
+ 'allow' => Zend_Validate_Hostname::ALLOW_DNS,
|
|
|
+ 'hostname' => null
|
|
|
+ );
|
|
|
+
|
|
|
+ /**
|
|
|
* Instantiates hostname validator for local use
|
|
|
*
|
|
|
- * You can pass a bitfield to determine what types of hostnames are allowed.
|
|
|
- * These bitfields are defined by the ALLOW_* constants in Zend_Validate_Hostname
|
|
|
- * The default is to allow DNS hostnames only
|
|
|
+ * The following option keys are supported:
|
|
|
+ * 'hostname' => A hostname validator, see Zend_Validate_Hostname
|
|
|
+ * 'allow' => Options for the hostname validator, see Zend_Validate_Hostname::ALLOW_*
|
|
|
+ * 'mx' => If MX check should be enabled, boolean
|
|
|
+ * 'deep' => If a deep MX check should be done, boolean
|
|
|
*
|
|
|
- * @param integer $allow OPTIONAL
|
|
|
- * @param bool $validateMx OPTIONAL
|
|
|
- * @param Zend_Validate_Hostname $hostnameValidator OPTIONAL
|
|
|
+ * @param array|Zend_Config $options OPTIONAL
|
|
|
* @return void
|
|
|
*/
|
|
|
- public function __construct($allow = Zend_Validate_Hostname::ALLOW_DNS, $validateMx = false, Zend_Validate_Hostname $hostnameValidator = null)
|
|
|
+ public function __construct($options = array())
|
|
|
+ {
|
|
|
+ if ($options instanceof Zend_Config) {
|
|
|
+ $options = $options->toArray();
|
|
|
+ } else if (!is_array($options)) {
|
|
|
+ $count = func_num_args();
|
|
|
+ if ($count > 1) {
|
|
|
+// @todo: Preperation for 2.0... needs to be cleared with the dev-team
|
|
|
+// trigger_error('Support for multiple arguments is deprecated in favor of a single options array', E_USER_NOTICE);
|
|
|
+ }
|
|
|
+
|
|
|
+ $options = func_get_args();
|
|
|
+ $temp['allow'] = array_shift($options);
|
|
|
+ if (!empty($options)) {
|
|
|
+ $temp['mx'] = array_shift($options);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!empty($options)) {
|
|
|
+ $temp['hostname'] = array_shift($options);
|
|
|
+ }
|
|
|
+
|
|
|
+ $options = $temp;
|
|
|
+ }
|
|
|
+
|
|
|
+ $options += $this->_options;
|
|
|
+ $this->setOptions($options);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns all set Options
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public function getOptions()
|
|
|
{
|
|
|
- $this->setValidateMx($validateMx);
|
|
|
- $this->setHostnameValidator($hostnameValidator, $allow);
|
|
|
+ return $this->_options;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set options for the email validator
|
|
|
+ *
|
|
|
+ * @param array $options
|
|
|
+ * @return Zend_Validate_EmailAddress fluid interface
|
|
|
+ */
|
|
|
+ public function setOptions(array $options = array())
|
|
|
+ {
|
|
|
+ if (array_key_exists('messages', $options)) {
|
|
|
+ $this->setMessages($options['messages']);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array_key_exists('hostname', $options)) {
|
|
|
+ if (array_key_exists('allow', $options)) {
|
|
|
+ $this->setHostnameValidator($options['hostname'], $options['allow']);
|
|
|
+ } else {
|
|
|
+ $this->setHostnameValidator($options['hostname']);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array_key_exists('mx', $options)) {
|
|
|
+ $this->setValidateMx($options['mx']);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array_key_exists('deep', $options)) {
|
|
|
+ $this->setDeepMxCheck($options['deep']);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array_key_exists('domain', $options)) {
|
|
|
+ $this->setDomainCheck($options['domain']);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $this;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -129,7 +218,7 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
}
|
|
|
|
|
|
if (!isset($this->_messageTemplates[$messageKeys])) {
|
|
|
- $this->hostnameValidator->setMessage($messageString, $messageKey);
|
|
|
+ $this->_options['hostname']->setMessage($messageString, $messageKey);
|
|
|
}
|
|
|
|
|
|
$this->_messageTemplates[$messageKeys] = $messageString;
|
|
|
@@ -143,7 +232,7 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
*/
|
|
|
public function getHostnameValidator()
|
|
|
{
|
|
|
- return $this->hostnameValidator;
|
|
|
+ return $this->_options['hostname'];
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -153,14 +242,17 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
*/
|
|
|
public function setHostnameValidator(Zend_Validate_Hostname $hostnameValidator = null, $allow = Zend_Validate_Hostname::ALLOW_DNS)
|
|
|
{
|
|
|
- if ($hostnameValidator === null) {
|
|
|
+ if (!$hostnameValidator) {
|
|
|
$hostnameValidator = new Zend_Validate_Hostname($allow);
|
|
|
}
|
|
|
- $this->hostnameValidator = $hostnameValidator;
|
|
|
+
|
|
|
+ $this->_options['hostname'] = $hostnameValidator;
|
|
|
+ $this->_options['allow'] = $allow;
|
|
|
+ return $this;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Whether MX checking via dns_get_mx is supported or not
|
|
|
+ * Whether MX checking via getmxrr is supported or not
|
|
|
*
|
|
|
* This currently only works on UNIX systems
|
|
|
*
|
|
|
@@ -168,7 +260,17 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
*/
|
|
|
public function validateMxSupported()
|
|
|
{
|
|
|
- return function_exists('dns_get_mx');
|
|
|
+ return function_exists('getmxrr');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the set validateMx option
|
|
|
+ *
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ public function getValidateMx()
|
|
|
+ {
|
|
|
+ return $this->_options['mx'];
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -176,11 +278,235 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
*
|
|
|
* This only applies when DNS hostnames are validated
|
|
|
*
|
|
|
- * @param boolean $allowed Set allowed to true to validate for MX records, and false to not validate them
|
|
|
+ * @param boolean $mx Set allowed to true to validate for MX records, and false to not validate them
|
|
|
+ * @return Zend_Validate_EmailAddress Fluid Interface
|
|
|
+ */
|
|
|
+ public function setValidateMx($mx)
|
|
|
+ {
|
|
|
+ if ((bool) $mx && !$this->validateMxSupported()) {
|
|
|
+ require_once 'Zend/Validate/Exception.php';
|
|
|
+ throw new Zend_Validate_Exception('MX checking not available on this system');
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->_options['mx'] = (bool) $mx;
|
|
|
+ return $this;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the set deepMxCheck option
|
|
|
+ *
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ public function getDeepMxCheck()
|
|
|
+ {
|
|
|
+ return $this->_options['deep'];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set whether we check MX record should be a deep validation
|
|
|
+ *
|
|
|
+ * @param boolean $deep Set deep to true to perform a deep validation process for MX records
|
|
|
+ * @return Zend_Validate_EmailAddress Fluid Interface
|
|
|
+ */
|
|
|
+ public function setDeepMxCheck($deep)
|
|
|
+ {
|
|
|
+ $this->_options['deep'] = (bool) $deep;
|
|
|
+ return $this;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the set domainCheck option
|
|
|
+ *
|
|
|
+ * @return unknown
|
|
|
+ */
|
|
|
+ public function getDomainCheck()
|
|
|
+ {
|
|
|
+ return $this->_options['domain'];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Sets if the domain should also be checked
|
|
|
+ * or only the local part of the email address
|
|
|
+ *
|
|
|
+ * @param boolean $domain
|
|
|
+ * @return Zend_Validate_EmailAddress Fluid Interface
|
|
|
+ */
|
|
|
+ public function setDomainCheck($domain = true)
|
|
|
+ {
|
|
|
+ $this->_options['domain'] = (boolean) $domain;
|
|
|
+ return $this;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns if the given host is reserved
|
|
|
+ *
|
|
|
+ * @param string $host
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ private function _isReserved($host){
|
|
|
+ if (!preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $host)) {
|
|
|
+ $host = gethostbyname($host);
|
|
|
+ }
|
|
|
+
|
|
|
+ $octet = explode('.',$host);
|
|
|
+ if ((int)$octet[0] >= 224) {
|
|
|
+ return true;
|
|
|
+ } else if (array_key_exists($octet[0], $this->_invalidIp)) {
|
|
|
+ foreach ((array)$this->_invalidIp[$octet[0]] as $subnetData) {
|
|
|
+ // we skip the first loop as we already know that octet matches
|
|
|
+ for ($i = 1; $i < 4; $i++) {
|
|
|
+ if (strpos($subnetData, $octet[$i]) !== $i * 4) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $host = explode("/", $subnetData);
|
|
|
+ $binaryHost = "";
|
|
|
+ $tmp = explode(".", $host[0]);
|
|
|
+ for ($i = 0; $i < 4 ; $i++) {
|
|
|
+ $binaryHost .= str_pad(decbin($tmp[$i]), 8, "0", STR_PAD_LEFT);
|
|
|
+ }
|
|
|
+
|
|
|
+ $segmentData = array(
|
|
|
+ 'network' => (int)$this->_binaryToIp(str_pad(substr($binaryHost, 0, $host[1]), 32, 0)),
|
|
|
+ 'broadcast' => (int)$this->_binaryToIp(str_pad(substr($binaryHost, 0, $host[1]), 32, 1))
|
|
|
+ );
|
|
|
+
|
|
|
+ for ($j = $i; $j < 4; $j++) {
|
|
|
+ if ((int)$octet[$j] < $segmentData['network'][$j] ||
|
|
|
+ (int)$octet[$j] > $segmentData['broadcast'][$j]) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Converts a binary string to an IP address
|
|
|
+ *
|
|
|
+ * @param string $binary
|
|
|
+ * @return mixed
|
|
|
+ */
|
|
|
+ private function _toIp($binary)
|
|
|
+ {
|
|
|
+ $ip = array();
|
|
|
+ $tmp = explode(".", chunk_split($binary, 8, "."));
|
|
|
+ for ($i = 0; $i < 4 ; $i++) {
|
|
|
+ $ip[$i] = bindec($tmp[$i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $ip;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Internal method to validate the local part of the email address
|
|
|
+ *
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ private function _validateLocalPart()
|
|
|
+ {
|
|
|
+ // First try to match the local part on the common dot-atom format
|
|
|
+ $result = false;
|
|
|
+
|
|
|
+ // Dot-atom characters are: 1*atext *("." 1*atext)
|
|
|
+ // atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*",
|
|
|
+ // "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~"
|
|
|
+ $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e';
|
|
|
+ if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->_localPart)) {
|
|
|
+ $result = true;
|
|
|
+ } else {
|
|
|
+ // Try quoted string format
|
|
|
+
|
|
|
+ // Quoted-string characters are: DQUOTE *([FWS] qtext/quoted-pair) [FWS] DQUOTE
|
|
|
+ // qtext: Non white space controls, and the rest of the US-ASCII characters not
|
|
|
+ // including "\" or the quote character
|
|
|
+ $noWsCtl = '\x01-\x08\x0b\x0c\x0e-\x1f\x7f';
|
|
|
+ $qtext = $noWsCtl . '\x21\x23-\x5b\x5d-\x7e';
|
|
|
+ $ws = '\x20\x09';
|
|
|
+ if (preg_match('/^\x22([' . $ws . $qtext . '])*[$ws]?\x22$/', $this->_localPart)) {
|
|
|
+ $result = true;
|
|
|
+ } else {
|
|
|
+ $this->_error(self::DOT_ATOM);
|
|
|
+ $this->_error(self::QUOTED_STRING);
|
|
|
+ $this->_error(self::INVALID_LOCAL_PART);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Internal method to validate the servers MX records
|
|
|
+ *
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ private function _validateMXRecords()
|
|
|
+ {
|
|
|
+ $result = true;
|
|
|
+ $mxHosts = array();
|
|
|
+ getmxrr($this->_hostname, $mxHosts);
|
|
|
+ if ($this->_options['deep'] && function_exists('checkdnsrr')) {
|
|
|
+ $validAddress = false;
|
|
|
+ $reserved = true;
|
|
|
+ foreach ($mxHosts as $hostname) {
|
|
|
+ $res = $this->_isReserved($hostname);
|
|
|
+ if (!$res) {
|
|
|
+ $reserved = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$res
|
|
|
+ && (checkdnsrr($hostname, "A")
|
|
|
+ || checkdnsrr($hostname, "AAAA")
|
|
|
+ || checkdnsrr($hostname, "A6"))) {
|
|
|
+ $validAddress = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$validAddress) {
|
|
|
+ $result = false;
|
|
|
+ if ($reserved) {
|
|
|
+ $this->_error(self::INVALID_NETWORK_SEGMENT);
|
|
|
+ } else {
|
|
|
+ $this->_error(self::INVALID_MX_RECORD);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Internal method to validate the hostname part of the email address
|
|
|
+ *
|
|
|
+ * @return boolean
|
|
|
*/
|
|
|
- public function setValidateMx($allowed)
|
|
|
+ private function _validateHostnamePart()
|
|
|
{
|
|
|
- $this->_validateMx = (bool) $allowed;
|
|
|
+ $hostname = $this->_options['hostname']->setTranslator($this->getTranslator())
|
|
|
+ ->isValid($this->_hostname);
|
|
|
+ if (!$hostname) {
|
|
|
+ $this->_error(self::INVALID_HOSTNAME);
|
|
|
+
|
|
|
+ // Get messages and errors from hostnameValidator
|
|
|
+ foreach ($this->_options['hostname']->getMessages() as $code => $message) {
|
|
|
+ $this->_messages[$code] = $message;
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach ($this->_options['hostname']->getErrors() as $error) {
|
|
|
+ $this->_errors[] = $error;
|
|
|
+ }
|
|
|
+ } else if ($this->_options['mx']) {
|
|
|
+ // MX check on hostname
|
|
|
+ $hostname = $this->_validateMXRecords();
|
|
|
+ }
|
|
|
+
|
|
|
+ return $hostname;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -201,9 +527,8 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- $matches = array();
|
|
|
- $length = true;
|
|
|
-
|
|
|
+ $matches = array();
|
|
|
+ $length = true;
|
|
|
$this->_setValue($value);
|
|
|
|
|
|
// Split email address up and disallow '..'
|
|
|
@@ -222,69 +547,19 @@ class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
|
|
|
}
|
|
|
|
|
|
// Match hostname part
|
|
|
- $hostnameResult = $this->hostnameValidator->setTranslator($this->getTranslator())
|
|
|
- ->isValid($this->_hostname);
|
|
|
- if (!$hostnameResult) {
|
|
|
- $this->_error(self::INVALID_HOSTNAME);
|
|
|
-
|
|
|
- // Get messages and errors from hostnameValidator
|
|
|
- foreach ($this->hostnameValidator->getMessages() as $code => $message) {
|
|
|
- $this->_messages[$code] = $message;
|
|
|
- }
|
|
|
- foreach ($this->hostnameValidator->getErrors() as $error) {
|
|
|
- $this->_errors[] = $error;
|
|
|
- }
|
|
|
- } else if ($this->_validateMx) {
|
|
|
- // MX check on hostname via dns_get_record()
|
|
|
- if ($this->validateMxSupported()) {
|
|
|
- $mxHosts = array();
|
|
|
- dns_get_mx($this->_hostname, $mxHosts);
|
|
|
- if (count($mxHosts) < 1) {
|
|
|
- $hostnameResult = false;
|
|
|
- $this->_error(self::INVALID_MX_RECORD);
|
|
|
- }
|
|
|
- } else {
|
|
|
- /**
|
|
|
- * MX checks are not supported by this system
|
|
|
- * @see Zend_Validate_Exception
|
|
|
- */
|
|
|
- require_once 'Zend/Validate/Exception.php';
|
|
|
- throw new Zend_Validate_Exception('Internal error: MX checking not available on this system');
|
|
|
- }
|
|
|
+ if ($this->_options['domain']) {
|
|
|
+ $hostname = $this->_validateHostnamePart();
|
|
|
}
|
|
|
|
|
|
- // First try to match the local part on the common dot-atom format
|
|
|
- $localResult = false;
|
|
|
-
|
|
|
- // Dot-atom characters are: 1*atext *("." 1*atext)
|
|
|
- // atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*",
|
|
|
- // "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~"
|
|
|
- $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e';
|
|
|
- if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->_localPart)) {
|
|
|
- $localResult = true;
|
|
|
- } else {
|
|
|
- // Try quoted string format
|
|
|
+ $local = $this->_validateLocalPart();
|
|
|
|
|
|
- // Quoted-string characters are: DQUOTE *([FWS] qtext/quoted-pair) [FWS] DQUOTE
|
|
|
- // qtext: Non white space controls, and the rest of the US-ASCII characters not
|
|
|
- // including "\" or the quote character
|
|
|
- $noWsCtl = '\x01-\x08\x0b\x0c\x0e-\x1f\x7f';
|
|
|
- $qtext = $noWsCtl . '\x21\x23-\x5b\x5d-\x7e';
|
|
|
- $ws = '\x20\x09';
|
|
|
- if (preg_match('/^\x22([' . $ws . $qtext . '])*[$ws]?\x22$/', $this->_localPart)) {
|
|
|
- $localResult = true;
|
|
|
- } else {
|
|
|
- $this->_error(self::DOT_ATOM);
|
|
|
- $this->_error(self::QUOTED_STRING);
|
|
|
- $this->_error(self::INVALID_LOCAL_PART);
|
|
|
+ // If both parts valid, return true
|
|
|
+ if ($local && $length) {
|
|
|
+ if (($this->_options['domain'] && $hostname) || !$this->_options['domain']) {
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // If both parts valid, return true
|
|
|
- if ($localResult && $hostnameResult && $length) {
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|