mirror of
https://github.com/egulias/EmailValidator.git
synced 2026-09-09 17:46:29 +00:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 19674b35a0 | |||
| 92fd7ea285 | |||
| 0d6268fde5 | |||
| e7dacfc97f | |||
| 758a77525b | |||
| 5642614492 | |||
| b8bb147f46 | |||
| cbfe3ee6f7 | |||
| 4b59310c1a | |||
| f463fbe542 | |||
| afc6adc0b9 | |||
| 58e44fb064 | |||
| 04c6cdf987 | |||
| cc9defe645 | |||
| 50aaa0b18f | |||
| de448a30fa | |||
| a7b385301d | |||
| f6447f8b99 | |||
| d4001715b2 | |||
| 4b7fcf6796 | |||
| 2a1145ffbf | |||
| af864423f5 | |||
| 12f16f70aa | |||
| 0afaa6a3b6 | |||
| 5631c3fe2e | |||
| c383717824 | |||
| aabed98198 | |||
| 3b0fd01aa3 | |||
| 4efe697504 | |||
| 7a4c5714f5 | |||
| 0a26375a7a | |||
| 773fe5f4a3 | |||
| 4a209951ee | |||
| a8b0bab5aa | |||
| cc0b91f311 | |||
| 8092ecaeff | |||
| f19defb373 | |||
| 9a518fb1bd | |||
| 9b184605e8 | |||
| 7a4842c60f | |||
| 687ab6a66e | |||
| 116d4054fa |
@@ -1,2 +1,4 @@
|
|||||||
|
.idea
|
||||||
|
composer.lock
|
||||||
report/
|
report/
|
||||||
vendor/
|
vendor/
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
filter:
|
||||||
|
excluded_paths:
|
||||||
|
- 'documentation/*'
|
||||||
|
- 'tests/*'
|
||||||
|
|
||||||
|
tools:
|
||||||
|
external_code_coverage:
|
||||||
|
runs: 1
|
||||||
+29
-12
@@ -1,20 +1,37 @@
|
|||||||
language: php
|
language: php
|
||||||
|
|
||||||
php:
|
matrix:
|
||||||
- 5.3
|
include:
|
||||||
- 5.4
|
- php: 5.3
|
||||||
- 5.5
|
dist: precise
|
||||||
- 5.6
|
env: deps=low
|
||||||
- hhvm
|
- php: 5.3
|
||||||
|
dist: precise
|
||||||
|
- php: 5.4
|
||||||
|
dist: trusty
|
||||||
|
- php: 5.5
|
||||||
|
dist: trusty
|
||||||
|
- php: 5.6
|
||||||
|
dist: xenial
|
||||||
|
- php: 7.0
|
||||||
|
dist: xenial
|
||||||
|
- php: 7.1
|
||||||
|
dist: bionic
|
||||||
|
- php: 7.2
|
||||||
|
dist: bionic
|
||||||
|
- php: 7.3
|
||||||
|
dist: bionic
|
||||||
|
- php: 7.4
|
||||||
|
dist: bionic
|
||||||
|
|
||||||
|
install:
|
||||||
|
- if [ "$deps" = "low" ]; then composer update --prefer-lowest; else composer install; fi
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- wget http://getcomposer.org/composer.phar
|
- mkdir -p build/logs
|
||||||
- php composer.phar install --dev --no-interaction
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- mkdir -p build/logs
|
- vendor/bin/phpunit --coverage-clover build/logs/clover.xml
|
||||||
- phpunit --coverage-clover build/logs/clover.xml
|
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
- php vendor/bin/coveralls
|
- php vendor/bin/coveralls
|
||||||
|
|
||||||
|
|||||||
@@ -1,59 +1,59 @@
|
|||||||
#EmailValidator#
|
#EmailValidator
|
||||||
[](https://travis-ci.org/egulias/EmailValidator) [](https://coveralls.io/r/egulias/EmailValidator?branch=master) [](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master) [](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6)
|
[](https://travis-ci.org/egulias/EmailValidator) [](https://coveralls.io/r/egulias/EmailValidator?branch=master) [](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master) [](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6)
|
||||||
=============================
|
=============================
|
||||||
With the help of
|
With the help of
|
||||||
|
|
||||||

|

|
||||||
##Installation##
|
##Installation##
|
||||||
|
|
||||||
Run the command below to install via Composer
|
Run the command below to install via Composer
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
composer require egulias/email-validator
|
composer require egulias/email-validator "~1.2"
|
||||||
```
|
```
|
||||||
|
|
||||||
##Usage##
|
##Usage##
|
||||||
|
|
||||||
Simple example:
|
Simple example:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Egulias\EmailValidator\EmailValidator;
|
use Egulias\EmailValidator\EmailValidator;
|
||||||
|
|
||||||
$validator = new EmailValidator;
|
$validator = new EmailValidator;
|
||||||
if ($validator->isValid($email)) {
|
if ($validator->isValid($email)) {
|
||||||
echo $email . ' is a valid email address';
|
echo $email . ' is a valid email address';
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
More advanced example (returns detailed diagnostic error codes):
|
More advanced example (returns detailed diagnostic error codes):
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Egulias\EmailValidator\EmailValidator;
|
use Egulias\EmailValidator\EmailValidator;
|
||||||
|
|
||||||
$validator = new EmailValidator;
|
$validator = new EmailValidator;
|
||||||
$email = 'dominic@sayers.cc';
|
$email = 'dominic@sayers.cc';
|
||||||
$result = $validator->isValid($email);
|
$result = $validator->isValid($email);
|
||||||
|
|
||||||
if ($result) {
|
if ($result) {
|
||||||
echo $email . ' is a valid email address';
|
echo $email . ' is a valid email address';
|
||||||
} else if ($validator->hasWarnings()) {
|
} else if ($validator->hasWarnings()) {
|
||||||
echo 'Warning! ' . $email . ' has unusual/deprecated features (result code ' . var_export($validator->getWarnings(), true) . ')';
|
echo 'Warning! ' . $email . ' has unusual/deprecated features (result code ' . var_export($validator->getWarnings(), true) . ')';
|
||||||
} else {
|
} else {
|
||||||
echo $email . ' is not a valid email address (result code ' . $validator->getError() . ')';
|
echo $email . ' is not a valid email address (result code ' . $validator->getError() . ')';
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
##Contributors##
|
##Contributors##
|
||||||
As this is a port from another library and work, here are other people related to the previous:
|
As this is a port from another library and work, here are other people related to the previous:
|
||||||
|
|
||||||
* Ricard Clau [@ricardclau](http://github.com/ricardclau): Performance against PHP built-in filter_var
|
* Ricard Clau [@ricardclau](http://github.com/ricardclau): Performance against PHP built-in filter_var
|
||||||
* Josepf Bielawski [@stloyd](http://github.com/stloyd): For its first re-work of Dominic's lib
|
* Josepf Bielawski [@stloyd](http://github.com/stloyd): For its first re-work of Dominic's lib
|
||||||
* Dominic Sayers [@dominicsayers](http://github.com/dominicsayers): The original isemail function
|
* Dominic Sayers [@dominicsayers](http://github.com/dominicsayers): The original isemail function
|
||||||
|
|
||||||
##License##
|
##License##
|
||||||
Released under the MIT License attached with this code.
|
Released under the MIT License attached with this code.
|
||||||
|
|
||||||
|
|||||||
+10
-12
@@ -2,27 +2,25 @@
|
|||||||
"name": "egulias/email-validator",
|
"name": "egulias/email-validator",
|
||||||
"description": "A library for validating emails",
|
"description": "A library for validating emails",
|
||||||
"homepage": "https://github.com/egulias/EmailValidator",
|
"homepage": "https://github.com/egulias/EmailValidator",
|
||||||
"type": "Library",
|
"keywords": ["email", "validation", "validator", "emailvalidation", "emailvalidator"],
|
||||||
"keywords": ["email", "validation", "validator"],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"authors": [
|
"authors": [
|
||||||
{"name": "Eduardo Gulias Davis"}
|
{"name": "Eduardo Gulias Davis"}
|
||||||
],
|
],
|
||||||
"extra": {
|
"require": {
|
||||||
"branch-alias": {
|
"php": ">=5.3.3",
|
||||||
"dev-master": "1.3.x-dev"
|
"doctrine/lexer": "^1.0.1"
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"require": {
|
"require-dev": {
|
||||||
"php": ">= 5.3.3",
|
"satooshi/php-coveralls": "^1.0.1",
|
||||||
"doctrine/lexer": "~1.0"
|
"phpunit/phpunit": "^4.8.36|^7.5.15"
|
||||||
},
|
|
||||||
"require-dev" : {
|
|
||||||
"satooshi/php-coveralls": "dev-master"
|
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": {
|
"psr-0": {
|
||||||
"Egulias\\": "src/"
|
"Egulias\\": "src/"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "phpunit"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
-586
@@ -1,586 +0,0 @@
|
|||||||
{
|
|
||||||
"_readme": [
|
|
||||||
"This file locks the dependencies of your project to a known state",
|
|
||||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
|
||||||
"This file is @generated automatically"
|
|
||||||
],
|
|
||||||
"hash": "9e9dff0cc08c7292600453e681201e13",
|
|
||||||
"packages": [
|
|
||||||
{
|
|
||||||
"name": "doctrine/lexer",
|
|
||||||
"version": "v1.0.1",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/doctrine/lexer.git",
|
|
||||||
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
|
|
||||||
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.2"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "1.0.x-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Doctrine\\Common\\Lexer\\": "lib/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Roman Borschel",
|
|
||||||
"email": "roman@code-factory.org"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Guilherme Blanco",
|
|
||||||
"email": "guilhermeblanco@gmail.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Johannes Schmitt",
|
|
||||||
"email": "schmittjoh@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
|
|
||||||
"homepage": "http://www.doctrine-project.org",
|
|
||||||
"keywords": [
|
|
||||||
"lexer",
|
|
||||||
"parser"
|
|
||||||
],
|
|
||||||
"time": "2014-09-09 13:34:57"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"packages-dev": [
|
|
||||||
{
|
|
||||||
"name": "guzzle/guzzle",
|
|
||||||
"version": "v3.9.2",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/guzzle/guzzle3.git",
|
|
||||||
"reference": "54991459675c1a2924122afbb0e5609ade581155"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/guzzle/guzzle3/zipball/54991459675c1a2924122afbb0e5609ade581155",
|
|
||||||
"reference": "54991459675c1a2924122afbb0e5609ade581155",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"ext-curl": "*",
|
|
||||||
"php": ">=5.3.3",
|
|
||||||
"symfony/event-dispatcher": "~2.1"
|
|
||||||
},
|
|
||||||
"replace": {
|
|
||||||
"guzzle/batch": "self.version",
|
|
||||||
"guzzle/cache": "self.version",
|
|
||||||
"guzzle/common": "self.version",
|
|
||||||
"guzzle/http": "self.version",
|
|
||||||
"guzzle/inflection": "self.version",
|
|
||||||
"guzzle/iterator": "self.version",
|
|
||||||
"guzzle/log": "self.version",
|
|
||||||
"guzzle/parser": "self.version",
|
|
||||||
"guzzle/plugin": "self.version",
|
|
||||||
"guzzle/plugin-async": "self.version",
|
|
||||||
"guzzle/plugin-backoff": "self.version",
|
|
||||||
"guzzle/plugin-cache": "self.version",
|
|
||||||
"guzzle/plugin-cookie": "self.version",
|
|
||||||
"guzzle/plugin-curlauth": "self.version",
|
|
||||||
"guzzle/plugin-error-response": "self.version",
|
|
||||||
"guzzle/plugin-history": "self.version",
|
|
||||||
"guzzle/plugin-log": "self.version",
|
|
||||||
"guzzle/plugin-md5": "self.version",
|
|
||||||
"guzzle/plugin-mock": "self.version",
|
|
||||||
"guzzle/plugin-oauth": "self.version",
|
|
||||||
"guzzle/service": "self.version",
|
|
||||||
"guzzle/stream": "self.version"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"doctrine/cache": "~1.3",
|
|
||||||
"monolog/monolog": "~1.0",
|
|
||||||
"phpunit/phpunit": "3.7.*",
|
|
||||||
"psr/log": "~1.0",
|
|
||||||
"symfony/class-loader": "~2.1",
|
|
||||||
"zendframework/zend-cache": "2.*,<2.3",
|
|
||||||
"zendframework/zend-log": "2.*,<2.3"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "3.9-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Guzzle": "src/",
|
|
||||||
"Guzzle\\Tests": "tests/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Michael Dowling",
|
|
||||||
"email": "mtdowling@gmail.com",
|
|
||||||
"homepage": "https://github.com/mtdowling"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Guzzle Community",
|
|
||||||
"homepage": "https://github.com/guzzle/guzzle/contributors"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
|
|
||||||
"homepage": "http://guzzlephp.org/",
|
|
||||||
"keywords": [
|
|
||||||
"client",
|
|
||||||
"curl",
|
|
||||||
"framework",
|
|
||||||
"http",
|
|
||||||
"http client",
|
|
||||||
"rest",
|
|
||||||
"web service"
|
|
||||||
],
|
|
||||||
"time": "2014-08-11 04:32:36"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "psr/log",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-fig/log.git",
|
|
||||||
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
|
|
||||||
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Psr\\Log\\": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "PHP-FIG",
|
|
||||||
"homepage": "http://www.php-fig.org/"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Common interface for logging libraries",
|
|
||||||
"keywords": [
|
|
||||||
"log",
|
|
||||||
"psr",
|
|
||||||
"psr-3"
|
|
||||||
],
|
|
||||||
"time": "2012-12-21 11:40:51"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "satooshi/php-coveralls",
|
|
||||||
"version": "dev-master",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/satooshi/php-coveralls.git",
|
|
||||||
"reference": "2fbf803803d179ab1082807308a67bbd5a760c70"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/2fbf803803d179ab1082807308a67bbd5a760c70",
|
|
||||||
"reference": "2fbf803803d179ab1082807308a67bbd5a760c70",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"ext-json": "*",
|
|
||||||
"ext-simplexml": "*",
|
|
||||||
"guzzle/guzzle": ">=2.7",
|
|
||||||
"php": ">=5.3",
|
|
||||||
"psr/log": "1.0.0",
|
|
||||||
"symfony/config": ">=2.0",
|
|
||||||
"symfony/console": ">=2.0",
|
|
||||||
"symfony/stopwatch": ">=2.2",
|
|
||||||
"symfony/yaml": ">=2.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"apigen/apigen": "2.8.*@stable",
|
|
||||||
"pdepend/pdepend": "dev-master as 2.0.0",
|
|
||||||
"phpmd/phpmd": "dev-master",
|
|
||||||
"phpunit/php-invoker": ">=1.1.0,<1.2.0",
|
|
||||||
"phpunit/phpunit": "3.7.*@stable",
|
|
||||||
"sebastian/finder-facade": "dev-master",
|
|
||||||
"sebastian/phpcpd": "1.4.*@stable",
|
|
||||||
"squizlabs/php_codesniffer": "1.4.*@stable",
|
|
||||||
"theseer/fdomdocument": "dev-master"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"symfony/http-kernel": "Allows Symfony integration"
|
|
||||||
},
|
|
||||||
"bin": [
|
|
||||||
"composer/bin/coveralls"
|
|
||||||
],
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "0.7-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Satooshi\\Component": "src/",
|
|
||||||
"Satooshi\\Bundle": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Kitamura Satoshi",
|
|
||||||
"email": "with.no.parachute@gmail.com",
|
|
||||||
"homepage": "https://www.facebook.com/satooshi.jp"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "PHP client library for Coveralls API",
|
|
||||||
"homepage": "https://github.com/satooshi/php-coveralls",
|
|
||||||
"keywords": [
|
|
||||||
"ci",
|
|
||||||
"coverage",
|
|
||||||
"github",
|
|
||||||
"test"
|
|
||||||
],
|
|
||||||
"time": "2014-11-11 15:35:34"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "symfony/config",
|
|
||||||
"version": "v2.6.1",
|
|
||||||
"target-dir": "Symfony/Component/Config",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/Config.git",
|
|
||||||
"reference": "84c0c150c1520995f09ea9e47e817068b353cb0f"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/Config/zipball/84c0c150c1520995f09ea9e47e817068b353cb0f",
|
|
||||||
"reference": "84c0c150c1520995f09ea9e47e817068b353cb0f",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.3",
|
|
||||||
"symfony/filesystem": "~2.3"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.6-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Symfony\\Component\\Config\\": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "http://symfony.com/contributors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Symfony Config Component",
|
|
||||||
"homepage": "http://symfony.com",
|
|
||||||
"time": "2014-12-02 20:19:20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "symfony/console",
|
|
||||||
"version": "v2.6.1",
|
|
||||||
"target-dir": "Symfony/Component/Console",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/Console.git",
|
|
||||||
"reference": "ef825fd9f809d275926547c9e57cbf14968793e8"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/Console/zipball/ef825fd9f809d275926547c9e57cbf14968793e8",
|
|
||||||
"reference": "ef825fd9f809d275926547c9e57cbf14968793e8",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.3"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"psr/log": "~1.0",
|
|
||||||
"symfony/event-dispatcher": "~2.1",
|
|
||||||
"symfony/process": "~2.1"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"psr/log": "For using the console logger",
|
|
||||||
"symfony/event-dispatcher": "",
|
|
||||||
"symfony/process": ""
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.6-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Symfony\\Component\\Console\\": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "http://symfony.com/contributors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Symfony Console Component",
|
|
||||||
"homepage": "http://symfony.com",
|
|
||||||
"time": "2014-12-02 20:19:20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "symfony/event-dispatcher",
|
|
||||||
"version": "v2.6.1",
|
|
||||||
"target-dir": "Symfony/Component/EventDispatcher",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/EventDispatcher.git",
|
|
||||||
"reference": "720fe9bca893df7ad1b4546649473b5afddf0216"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/720fe9bca893df7ad1b4546649473b5afddf0216",
|
|
||||||
"reference": "720fe9bca893df7ad1b4546649473b5afddf0216",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.3"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"psr/log": "~1.0",
|
|
||||||
"symfony/config": "~2.0",
|
|
||||||
"symfony/dependency-injection": "~2.6",
|
|
||||||
"symfony/expression-language": "~2.6",
|
|
||||||
"symfony/stopwatch": "~2.2"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"symfony/dependency-injection": "",
|
|
||||||
"symfony/http-kernel": ""
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.6-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Symfony\\Component\\EventDispatcher\\": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "http://symfony.com/contributors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Symfony EventDispatcher Component",
|
|
||||||
"homepage": "http://symfony.com",
|
|
||||||
"time": "2014-12-02 20:19:20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "symfony/filesystem",
|
|
||||||
"version": "v2.6.1",
|
|
||||||
"target-dir": "Symfony/Component/Filesystem",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/Filesystem.git",
|
|
||||||
"reference": "ff6efc95256cb33031933729e68b01d720b5436b"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/ff6efc95256cb33031933729e68b01d720b5436b",
|
|
||||||
"reference": "ff6efc95256cb33031933729e68b01d720b5436b",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.3"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.6-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Symfony\\Component\\Filesystem\\": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "http://symfony.com/contributors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Symfony Filesystem Component",
|
|
||||||
"homepage": "http://symfony.com",
|
|
||||||
"time": "2014-12-02 20:19:20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "symfony/stopwatch",
|
|
||||||
"version": "v2.6.1",
|
|
||||||
"target-dir": "Symfony/Component/Stopwatch",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/Stopwatch.git",
|
|
||||||
"reference": "261abd360cfb6ac65ea93ffd82073e2011d034fc"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/261abd360cfb6ac65ea93ffd82073e2011d034fc",
|
|
||||||
"reference": "261abd360cfb6ac65ea93ffd82073e2011d034fc",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.3"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.6-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Symfony\\Component\\Stopwatch\\": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "http://symfony.com/contributors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Symfony Stopwatch Component",
|
|
||||||
"homepage": "http://symfony.com",
|
|
||||||
"time": "2014-12-02 20:19:20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "symfony/yaml",
|
|
||||||
"version": "v2.6.1",
|
|
||||||
"target-dir": "Symfony/Component/Yaml",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/symfony/Yaml.git",
|
|
||||||
"reference": "3346fc090a3eb6b53d408db2903b241af51dcb20"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/3346fc090a3eb6b53d408db2903b241af51dcb20",
|
|
||||||
"reference": "3346fc090a3eb6b53d408db2903b241af51dcb20",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.3.3"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"extra": {
|
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.6-dev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-0": {
|
|
||||||
"Symfony\\Component\\Yaml\\": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Symfony Community",
|
|
||||||
"homepage": "http://symfony.com/contributors"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Fabien Potencier",
|
|
||||||
"email": "fabien@symfony.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "Symfony Yaml Component",
|
|
||||||
"homepage": "http://symfony.com",
|
|
||||||
"time": "2014-12-02 20:19:20"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"aliases": [],
|
|
||||||
"minimum-stability": "stable",
|
|
||||||
"stability-flags": {
|
|
||||||
"satooshi/php-coveralls": 20
|
|
||||||
},
|
|
||||||
"prefer-stable": false,
|
|
||||||
"prefer-lowest": false,
|
|
||||||
"platform": {
|
|
||||||
"php": ">= 5.3.3"
|
|
||||||
},
|
|
||||||
"platform-dev": []
|
|
||||||
}
|
|
||||||
@@ -1,89 +1,89 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
||||||
<title>The BNF from RFC 5321 defining parts of a valid SMTP address</title>
|
<title>The BNF from RFC 5321 defining parts of a valid SMTP address</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<pre style="font-size:11px;">
|
<pre style="font-size:11px;">
|
||||||
Mailbox = Local-part "@" ( Domain / address-literal )
|
Mailbox = Local-part "@" ( Domain / address-literal )
|
||||||
|
|
||||||
Local-part = Dot-string / Quoted-string
|
Local-part = Dot-string / Quoted-string
|
||||||
; MAY be case-sensitive
|
; MAY be case-sensitive
|
||||||
|
|
||||||
|
|
||||||
Dot-string = Atom *("." Atom)
|
Dot-string = Atom *("." Atom)
|
||||||
|
|
||||||
Atom = 1*atext
|
Atom = 1*atext
|
||||||
|
|
||||||
Quoted-string = DQUOTE *QcontentSMTP DQUOTE
|
Quoted-string = DQUOTE *QcontentSMTP DQUOTE
|
||||||
|
|
||||||
QcontentSMTP = qtextSMTP / quoted-pairSMTP
|
QcontentSMTP = qtextSMTP / quoted-pairSMTP
|
||||||
|
|
||||||
quoted-pairSMTP = %d92 %d32-126
|
quoted-pairSMTP = %d92 %d32-126
|
||||||
; i.e., backslash followed by any ASCII
|
; i.e., backslash followed by any ASCII
|
||||||
; graphic (including itself) or SPace
|
; graphic (including itself) or SPace
|
||||||
|
|
||||||
qtextSMTP = %d32-33 / %d35-91 / %d93-126
|
qtextSMTP = %d32-33 / %d35-91 / %d93-126
|
||||||
; i.e., within a quoted string, any
|
; i.e., within a quoted string, any
|
||||||
; ASCII graphic or space is permitted
|
; ASCII graphic or space is permitted
|
||||||
; without blackslash-quoting except
|
; without blackslash-quoting except
|
||||||
; double-quote and the backslash itself.
|
; double-quote and the backslash itself.
|
||||||
|
|
||||||
Domain = sub-domain *("." sub-domain)
|
Domain = sub-domain *("." sub-domain)
|
||||||
|
|
||||||
sub-domain = Let-dig [Ldh-str]
|
sub-domain = Let-dig [Ldh-str]
|
||||||
|
|
||||||
Let-dig = ALPHA / DIGIT
|
Let-dig = ALPHA / DIGIT
|
||||||
|
|
||||||
Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig
|
Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig
|
||||||
|
|
||||||
address-literal = "[" ( IPv4-address-literal /
|
address-literal = "[" ( IPv4-address-literal /
|
||||||
IPv6-address-literal /
|
IPv6-address-literal /
|
||||||
General-address-literal ) "]"
|
General-address-literal ) "]"
|
||||||
; See Section 4.1.3
|
; See Section 4.1.3
|
||||||
|
|
||||||
IPv4-address-literal = Snum 3("." Snum)
|
IPv4-address-literal = Snum 3("." Snum)
|
||||||
|
|
||||||
IPv6-address-literal = "IPv6:" IPv6-addr
|
IPv6-address-literal = "IPv6:" IPv6-addr
|
||||||
|
|
||||||
General-address-literal = Standardized-tag ":" 1*dcontent
|
General-address-literal = Standardized-tag ":" 1*dcontent
|
||||||
|
|
||||||
Standardized-tag = Ldh-str
|
Standardized-tag = Ldh-str
|
||||||
; Standardized-tag MUST be specified in a
|
; Standardized-tag MUST be specified in a
|
||||||
; Standards-Track RFC and registered with IANA
|
; Standards-Track RFC and registered with IANA
|
||||||
|
|
||||||
dcontent = %d33-90 / ; Printable US-ASCII
|
dcontent = %d33-90 / ; Printable US-ASCII
|
||||||
%d94-126 ; excl. "[", "\", "]"
|
%d94-126 ; excl. "[", "\", "]"
|
||||||
|
|
||||||
Snum = 1*3DIGIT
|
Snum = 1*3DIGIT
|
||||||
; representing a decimal integer
|
; representing a decimal integer
|
||||||
; value in the range 0 through 255
|
; value in the range 0 through 255
|
||||||
|
|
||||||
IPv6-addr = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp
|
IPv6-addr = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp
|
||||||
|
|
||||||
IPv6-hex = 1*4HEXDIG
|
IPv6-hex = 1*4HEXDIG
|
||||||
|
|
||||||
IPv6-full = IPv6-hex 7(":" IPv6-hex)
|
IPv6-full = IPv6-hex 7(":" IPv6-hex)
|
||||||
|
|
||||||
IPv6-comp = [IPv6-hex *5(":" IPv6-hex)] "::"
|
IPv6-comp = [IPv6-hex *5(":" IPv6-hex)] "::"
|
||||||
[IPv6-hex *5(":" IPv6-hex)]
|
[IPv6-hex *5(":" IPv6-hex)]
|
||||||
; The "::" represents at least 2 16-bit groups of
|
; The "::" represents at least 2 16-bit groups of
|
||||||
; zeros. No more than 6 groups in addition to the
|
; zeros. No more than 6 groups in addition to the
|
||||||
; "::" may be present.
|
; "::" may be present.
|
||||||
|
|
||||||
IPv6v4-full = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal
|
IPv6v4-full = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal
|
||||||
|
|
||||||
IPv6v4-comp = [IPv6-hex *3(":" IPv6-hex)] "::"
|
IPv6v4-comp = [IPv6-hex *3(":" IPv6-hex)] "::"
|
||||||
[IPv6-hex *3(":" IPv6-hex) ":"]
|
[IPv6-hex *3(":" IPv6-hex) ":"]
|
||||||
IPv4-address-literal
|
IPv4-address-literal
|
||||||
; The "::" represents at least 2 16-bit groups of
|
; The "::" represents at least 2 16-bit groups of
|
||||||
; zeros. No more than 4 groups in addition to the
|
; zeros. No more than 4 groups in addition to the
|
||||||
; "::" and IPv4-address-literal may be present.
|
; "::" and IPv4-address-literal may be present.
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+141
-141
@@ -1,141 +1,141 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
||||||
<title>The BNF from RFC 5322 defining parts of a valid internet message address</title>
|
<title>The BNF from RFC 5322 defining parts of a valid internet message address</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<pre style="font-size:11px;">
|
<pre style="font-size:11px;">
|
||||||
addr-spec = local-part "@" domain
|
addr-spec = local-part "@" domain
|
||||||
|
|
||||||
local-part = dot-atom / quoted-string / obs-local-part
|
local-part = dot-atom / quoted-string / obs-local-part
|
||||||
|
|
||||||
dot-atom = [CFWS] dot-atom-text [CFWS]
|
dot-atom = [CFWS] dot-atom-text [CFWS]
|
||||||
|
|
||||||
CFWS = (1*([FWS] comment) [FWS]) / FWS
|
CFWS = (1*([FWS] comment) [FWS]) / FWS
|
||||||
|
|
||||||
FWS = ([*WSP CRLF] 1*WSP) / obs-FWS
|
FWS = ([*WSP CRLF] 1*WSP) / obs-FWS
|
||||||
; Folding white space
|
; Folding white space
|
||||||
|
|
||||||
WSP = SP / HTAB ; white space
|
WSP = SP / HTAB ; white space
|
||||||
|
|
||||||
obs-FWS = 1*([CRLF] WSP) ; As amended in erratum #1908
|
obs-FWS = 1*([CRLF] WSP) ; As amended in erratum #1908
|
||||||
|
|
||||||
ctext = %d33-39 / ; Printable US-ASCII
|
ctext = %d33-39 / ; Printable US-ASCII
|
||||||
%d42-91 / ; characters not including
|
%d42-91 / ; characters not including
|
||||||
%d93-126 / ; "(", ")", or "\"
|
%d93-126 / ; "(", ")", or "\"
|
||||||
obs-ctext
|
obs-ctext
|
||||||
|
|
||||||
obs-ctext = obs-NO-WS-CTL
|
obs-ctext = obs-NO-WS-CTL
|
||||||
ccontent = ctext / quoted-pair / comment
|
ccontent = ctext / quoted-pair / comment
|
||||||
|
|
||||||
comment = "(" *([FWS] ccontent) [FWS] ")"
|
comment = "(" *([FWS] ccontent) [FWS] ")"
|
||||||
|
|
||||||
dot-atom-text = 1*atext *("." 1*atext)
|
dot-atom-text = 1*atext *("." 1*atext)
|
||||||
|
|
||||||
atext = ALPHA / DIGIT / ; Printable US-ASCII
|
atext = ALPHA / DIGIT / ; Printable US-ASCII
|
||||||
"!" / "#" / ; characters not including
|
"!" / "#" / ; characters not including
|
||||||
"$" / "%" / ; specials. Used for atoms.
|
"$" / "%" / ; specials. Used for atoms.
|
||||||
"&" / "'" /
|
"&" / "'" /
|
||||||
"*" / "+" /
|
"*" / "+" /
|
||||||
"-" / "/" /
|
"-" / "/" /
|
||||||
"=" / "?" /
|
"=" / "?" /
|
||||||
"^" / "_" /
|
"^" / "_" /
|
||||||
"`" / "{" /
|
"`" / "{" /
|
||||||
"|" / "}" /
|
"|" / "}" /
|
||||||
"~"
|
"~"
|
||||||
|
|
||||||
specials = "(" / ")" / ; Special characters that do
|
specials = "(" / ")" / ; Special characters that do
|
||||||
"<" / ">" / ; not appear in atext
|
"<" / ">" / ; not appear in atext
|
||||||
"[" / "]" /
|
"[" / "]" /
|
||||||
":" / ";" /
|
":" / ";" /
|
||||||
"@" / "\" /
|
"@" / "\" /
|
||||||
"," / "." /
|
"," / "." /
|
||||||
DQUOTE
|
DQUOTE
|
||||||
|
|
||||||
quoted-string = [CFWS]
|
quoted-string = [CFWS]
|
||||||
DQUOTE *([FWS] qcontent) [FWS] DQUOTE
|
DQUOTE *([FWS] qcontent) [FWS] DQUOTE
|
||||||
[CFWS]
|
[CFWS]
|
||||||
|
|
||||||
qcontent = qtext / quoted-pair
|
qcontent = qtext / quoted-pair
|
||||||
|
|
||||||
qtext = %d33 / ; Printable US-ASCII
|
qtext = %d33 / ; Printable US-ASCII
|
||||||
%d35-91 / ; characters not including
|
%d35-91 / ; characters not including
|
||||||
%d93-126 / ; "\" or the quote character
|
%d93-126 / ; "\" or the quote character
|
||||||
obs-qtext
|
obs-qtext
|
||||||
|
|
||||||
obs-qtext = obs-NO-WS-CTL
|
obs-qtext = obs-NO-WS-CTL
|
||||||
|
|
||||||
obs-NO-WS-CTL = %d1-8 / ; US-ASCII control
|
obs-NO-WS-CTL = %d1-8 / ; US-ASCII control
|
||||||
%d11 / ; characters that do not
|
%d11 / ; characters that do not
|
||||||
%d12 / ; include the carriage
|
%d12 / ; include the carriage
|
||||||
%d14-31 / ; return, line feed, and
|
%d14-31 / ; return, line feed, and
|
||||||
%d127 ; white space characters
|
%d127 ; white space characters
|
||||||
|
|
||||||
quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
|
quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
|
||||||
|
|
||||||
VCHAR = %x21-7E ; visible (printing) characters
|
VCHAR = %x21-7E ; visible (printing) characters
|
||||||
|
|
||||||
obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)
|
obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)
|
||||||
|
|
||||||
obs-local-part = word *("." word)
|
obs-local-part = word *("." word)
|
||||||
|
|
||||||
word = atom / quoted-string
|
word = atom / quoted-string
|
||||||
|
|
||||||
atom = [CFWS] 1*atext [CFWS]
|
atom = [CFWS] 1*atext [CFWS]
|
||||||
|
|
||||||
domain = dot-atom / domain-literal / obs-domain
|
domain = dot-atom / domain-literal / obs-domain
|
||||||
|
|
||||||
domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
|
domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
|
||||||
|
|
||||||
dtext = %d33-90 / ; Printable US-ASCII
|
dtext = %d33-90 / ; Printable US-ASCII
|
||||||
%d94-126 / ; characters not including
|
%d94-126 / ; characters not including
|
||||||
obs-dtext ; "[", "]", or "\"
|
obs-dtext ; "[", "]", or "\"
|
||||||
|
|
||||||
obs-dtext = obs-NO-WS-CTL / quoted-pair
|
obs-dtext = obs-NO-WS-CTL / quoted-pair
|
||||||
|
|
||||||
obs-domain = atom *("." atom)
|
obs-domain = atom *("." atom)
|
||||||
|
|
||||||
NB For SMTP mail, the domain-literal is restricted by RFC5321 as follows:
|
NB For SMTP mail, the domain-literal is restricted by RFC5321 as follows:
|
||||||
|
|
||||||
Mailbox = Local-part "@" ( Domain / address-literal )
|
Mailbox = Local-part "@" ( Domain / address-literal )
|
||||||
|
|
||||||
address-literal = "[" ( IPv4-address-literal /
|
address-literal = "[" ( IPv4-address-literal /
|
||||||
IPv6-address-literal /
|
IPv6-address-literal /
|
||||||
General-address-literal ) "]"
|
General-address-literal ) "]"
|
||||||
|
|
||||||
IPv4-address-literal = Snum 3("." Snum)
|
IPv4-address-literal = Snum 3("." Snum)
|
||||||
|
|
||||||
IPv6-address-literal = "IPv6:" IPv6-addr
|
IPv6-address-literal = "IPv6:" IPv6-addr
|
||||||
|
|
||||||
Snum = 1*3DIGIT
|
Snum = 1*3DIGIT
|
||||||
; representing a decimal integer
|
; representing a decimal integer
|
||||||
; value in the range 0 through 255
|
; value in the range 0 through 255
|
||||||
|
|
||||||
IPv6-addr = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp
|
IPv6-addr = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp
|
||||||
|
|
||||||
IPv6-hex = 1*4HEXDIG
|
IPv6-hex = 1*4HEXDIG
|
||||||
|
|
||||||
IPv6-full = IPv6-hex 7(":" IPv6-hex)
|
IPv6-full = IPv6-hex 7(":" IPv6-hex)
|
||||||
|
|
||||||
IPv6-comp = [IPv6-hex *5(":" IPv6-hex)] "::"
|
IPv6-comp = [IPv6-hex *5(":" IPv6-hex)] "::"
|
||||||
[IPv6-hex *5(":" IPv6-hex)]
|
[IPv6-hex *5(":" IPv6-hex)]
|
||||||
; The "::" represents at least 2 16-bit groups of
|
; The "::" represents at least 2 16-bit groups of
|
||||||
; zeros. No more than 6 groups in addition to the
|
; zeros. No more than 6 groups in addition to the
|
||||||
; "::" may be present.
|
; "::" may be present.
|
||||||
|
|
||||||
IPv6v4-full = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal
|
IPv6v4-full = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal
|
||||||
|
|
||||||
IPv6v4-comp = [IPv6-hex *3(":" IPv6-hex)] "::"
|
IPv6v4-comp = [IPv6-hex *3(":" IPv6-hex)] "::"
|
||||||
[IPv6-hex *3(":" IPv6-hex) ":"]
|
[IPv6-hex *3(":" IPv6-hex) ":"]
|
||||||
IPv4-address-literal
|
IPv4-address-literal
|
||||||
; The "::" represents at least 2 16-bit groups of
|
; The "::" represents at least 2 16-bit groups of
|
||||||
; zeros. No more than 4 groups in addition to the
|
; zeros. No more than 4 groups in addition to the
|
||||||
; "::" and IPv4-address-literal may be present.
|
; "::" and IPv4-address-literal may be present.
|
||||||
|
|
||||||
</pre>
|
</pre>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
convertWarningsToExceptions="true"
|
convertWarningsToExceptions="true"
|
||||||
processIsolation="false"
|
processIsolation="false"
|
||||||
stopOnFailure="false"
|
stopOnFailure="false"
|
||||||
syntaxCheck="false"
|
|
||||||
bootstrap="tests/bootstrap.php"
|
bootstrap="tests/bootstrap.php"
|
||||||
>
|
>
|
||||||
<testsuites>
|
<testsuites>
|
||||||
|
|||||||
@@ -67,24 +67,32 @@ class EmailLexer extends AbstractLexer
|
|||||||
"\n" => self::S_LF,
|
"\n" => self::S_LF,
|
||||||
"\r\n" => self::CRLF,
|
"\r\n" => self::CRLF,
|
||||||
'IPv6' => self::S_IPV6TAG,
|
'IPv6' => self::S_IPV6TAG,
|
||||||
'<' => self::S_LOWERTHAN,
|
|
||||||
'>' => self::S_GREATERTHAN,
|
|
||||||
'{' => self::S_OPENQBRACKET,
|
'{' => self::S_OPENQBRACKET,
|
||||||
'}' => self::S_CLOSEQBRACKET,
|
'}' => self::S_CLOSEQBRACKET,
|
||||||
'' => self::S_EMPTY,
|
'' => self::S_EMPTY,
|
||||||
'\0' => self::C_NUL,
|
'\0' => self::C_NUL,
|
||||||
);
|
);
|
||||||
|
|
||||||
protected $invalidASCII = array(226 => 1,);
|
|
||||||
|
|
||||||
protected $hasInvalidTokens = false;
|
protected $hasInvalidTokens = false;
|
||||||
|
|
||||||
protected $previous;
|
protected $previous;
|
||||||
|
|
||||||
|
private static $nullToken = array(
|
||||||
|
'value' => '',
|
||||||
|
'type' => null,
|
||||||
|
'position' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->previous = $this->token = self::$nullToken;
|
||||||
|
}
|
||||||
|
|
||||||
public function reset()
|
public function reset()
|
||||||
{
|
{
|
||||||
$this->hasInvalidTokens = false;
|
$this->hasInvalidTokens = false;
|
||||||
parent::reset();
|
parent::reset();
|
||||||
|
$this->previous = $this->token = self::$nullToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasInvalidTokens()
|
public function hasInvalidTokens()
|
||||||
@@ -126,8 +134,10 @@ class EmailLexer extends AbstractLexer
|
|||||||
public function moveNext()
|
public function moveNext()
|
||||||
{
|
{
|
||||||
$this->previous = $this->token;
|
$this->previous = $this->token;
|
||||||
|
$hasNext = parent::moveNext();
|
||||||
|
$this->token = $this->token ?: self::$nullToken;
|
||||||
|
|
||||||
return parent::moveNext();
|
return $hasNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -138,7 +148,8 @@ class EmailLexer extends AbstractLexer
|
|||||||
protected function getCatchablePatterns()
|
protected function getCatchablePatterns()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'[a-zA-Z_]+[46]?',
|
'[a-zA-Z_]+[46]?', //ASCII and domain literal
|
||||||
|
'[^\x00-\x7F]', //UTF-8
|
||||||
'[0-9]+',
|
'[0-9]+',
|
||||||
'\r\n',
|
'\r\n',
|
||||||
'::',
|
'::',
|
||||||
@@ -179,11 +190,6 @@ class EmailLexer extends AbstractLexer
|
|||||||
return self::INVALID;
|
return self::INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isASCIIInvalid($value)) {
|
|
||||||
$this->hasInvalidTokens = true;
|
|
||||||
return self::INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::GENERIC;
|
return self::GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,19 +215,6 @@ class EmailLexer extends AbstractLexer
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $value
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function isASCIIInvalid($value)
|
|
||||||
{
|
|
||||||
if (isset($this->invalidASCII[ord($value)])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $value
|
* @param $value
|
||||||
* @return bool
|
* @return bool
|
||||||
|
|||||||
@@ -7,49 +7,52 @@ namespace Egulias\EmailValidator;
|
|||||||
*
|
*
|
||||||
* @author Eduardo Gulias Davis <me@egulias.com>
|
* @author Eduardo Gulias Davis <me@egulias.com>
|
||||||
*/
|
*/
|
||||||
class EmailValidator
|
class EmailValidator implements EmailValidatorInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Critical validation errors used to indicate that
|
||||||
|
* an email address is invalid:
|
||||||
|
*/
|
||||||
const ERR_CONSECUTIVEATS = 128;
|
const ERR_CONSECUTIVEATS = 128;
|
||||||
const ERR_EXPECTING_DTEXT = 129;
|
const ERR_EXPECTING_DTEXT = 129;
|
||||||
const ERR_NOLOCALPART = 130;
|
const ERR_NOLOCALPART = 130;
|
||||||
const ERR_NODOMAIN = 131;
|
const ERR_NODOMAIN = 131;
|
||||||
const ERR_CONSECUTIVEDOTS = 132;
|
const ERR_CONSECUTIVEDOTS = 132;
|
||||||
const ERR_ATEXT_AFTER_CFWS = 133;
|
const ERR_ATEXT_AFTER_CFWS = 133;
|
||||||
const ERR_ATEXT_AFTER_QS = 134;
|
|
||||||
const ERR_ATEXT_AFTER_DOMLIT = 135;
|
|
||||||
const ERR_EXPECTING_QPAIR = 136;
|
const ERR_EXPECTING_QPAIR = 136;
|
||||||
const ERR_EXPECTING_ATEXT = 137;
|
const ERR_EXPECTING_ATEXT = 137;
|
||||||
const ERR_EXPECTING_QTEXT = 138;
|
|
||||||
const ERR_EXPECTING_CTEXT = 139;
|
const ERR_EXPECTING_CTEXT = 139;
|
||||||
const ERR_BACKSLASHEND = 140;
|
|
||||||
const ERR_DOT_START = 141;
|
const ERR_DOT_START = 141;
|
||||||
const ERR_DOT_END = 142;
|
const ERR_DOT_END = 142;
|
||||||
const ERR_DOMAINHYPHENSTART = 143;
|
|
||||||
const ERR_DOMAINHYPHENEND = 144;
|
const ERR_DOMAINHYPHENEND = 144;
|
||||||
const ERR_UNCLOSEDQUOTEDSTR = 145;
|
const ERR_UNCLOSEDQUOTEDSTR = 145;
|
||||||
const ERR_UNCLOSEDCOMMENT = 146;
|
const ERR_UNCLOSEDCOMMENT = 146;
|
||||||
const ERR_UNCLOSEDDOMLIT = 147;
|
|
||||||
const ERR_FWS_CRLF_X2 = 148;
|
const ERR_FWS_CRLF_X2 = 148;
|
||||||
const ERR_FWS_CRLF_END = 149;
|
const ERR_FWS_CRLF_END = 149;
|
||||||
const ERR_CR_NO_LF = 150;
|
const ERR_CR_NO_LF = 150;
|
||||||
const ERR_DEPREC_REACHED = 151;
|
const ERR_DEPREC_REACHED = 151;
|
||||||
|
const ERR_UNOPENEDCOMMENT = 152;
|
||||||
|
const ERR_ATEXT_AFTER_QS = 134; // not in use
|
||||||
|
const ERR_ATEXT_AFTER_DOMLIT = 135; // not in use
|
||||||
|
const ERR_EXPECTING_QTEXT = 138; // not in use
|
||||||
|
const ERR_BACKSLASHEND = 140; // not in use
|
||||||
|
const ERR_DOMAINHYPHENSTART = 143; // not in use
|
||||||
|
const ERR_UNCLOSEDDOMLIT = 147; // not in use
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Informational validation warnings regarding unusual or
|
||||||
|
* deprecated features found in an email address:
|
||||||
|
*/
|
||||||
|
// Address is valid for SMTP (RFC-5321), but has unusual elements.
|
||||||
const RFC5321_TLD = 9;
|
const RFC5321_TLD = 9;
|
||||||
const RFC5321_TLDNUMERIC = 10;
|
|
||||||
const RFC5321_QUOTEDSTRING = 11;
|
const RFC5321_QUOTEDSTRING = 11;
|
||||||
const RFC5321_ADDRESSLITERAL = 12;
|
const RFC5321_ADDRESSLITERAL = 12;
|
||||||
const RFC5321_IPV6DEPRECATED = 13;
|
const RFC5321_IPV6DEPRECATED = 13;
|
||||||
const CFWS_COMMENT = 17;
|
const RFC5321_TLDNUMERIC = 10; // not in use
|
||||||
const CFWS_FWS = 18;
|
// Address is only valid according to the broad
|
||||||
const DEPREC_LOCALPART = 33;
|
// definition of RFC-5322. It is otherwise invalid.
|
||||||
const DEPREC_FWS = 34;
|
|
||||||
const DEPREC_QTEXT = 35;
|
|
||||||
const DEPREC_QP = 36;
|
|
||||||
const DEPREC_COMMENT = 37;
|
|
||||||
const DEPREC_CTEXT = 38;
|
|
||||||
const DEPREC_CFWS_NEAR_AT = 49;
|
|
||||||
const RFC5322_LOCAL_TOOLONG = 64;
|
const RFC5322_LOCAL_TOOLONG = 64;
|
||||||
const RFC5322_LABEL_TOOLONG = 63;
|
const RFC5322_LABEL_TOOLONG = 63;
|
||||||
const RFC5322_DOMAIN = 65;
|
|
||||||
const RFC5322_TOOLONG = 66;
|
const RFC5322_TOOLONG = 66;
|
||||||
const RFC5322_DOMAIN_TOOLONG = 255;
|
const RFC5322_DOMAIN_TOOLONG = 255;
|
||||||
const RFC5322_DOMAINLITERAL = 70;
|
const RFC5322_DOMAINLITERAL = 70;
|
||||||
@@ -60,12 +63,48 @@ class EmailValidator
|
|||||||
const RFC5322_IPV6_MAXGRPS = 75;
|
const RFC5322_IPV6_MAXGRPS = 75;
|
||||||
const RFC5322_IPV6_COLONSTRT = 76;
|
const RFC5322_IPV6_COLONSTRT = 76;
|
||||||
const RFC5322_IPV6_COLONEND = 77;
|
const RFC5322_IPV6_COLONEND = 77;
|
||||||
|
const RFC5322_DOMAIN = 65; // not in use
|
||||||
|
// Address contains deprecated elements, but may
|
||||||
|
// still be valid in restricted contexts.
|
||||||
|
const DEPREC_QP = 36;
|
||||||
|
const DEPREC_COMMENT = 37;
|
||||||
|
const DEPREC_CFWS_NEAR_AT = 49;
|
||||||
|
const DEPREC_LOCALPART = 33; // not in use
|
||||||
|
const DEPREC_FWS = 34; // not in use
|
||||||
|
const DEPREC_QTEXT = 35; // not in use
|
||||||
|
const DEPREC_CTEXT = 38; // not in use
|
||||||
|
// Address is valid within the message,
|
||||||
|
// but cannot be used unmodified in the envelope.
|
||||||
|
const CFWS_COMMENT = 17;
|
||||||
|
const CFWS_FWS = 18;
|
||||||
|
// Hostname DNS checks were unsuccessful.
|
||||||
const DNSWARN_NO_MX_RECORD = 5;
|
const DNSWARN_NO_MX_RECORD = 5;
|
||||||
const DNSWARN_NO_RECORD = 6;
|
const DNSWARN_NO_RECORD = 6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EmailParser
|
||||||
|
*/
|
||||||
protected $parser;
|
protected $parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains any informational warnings regarding unusual/deprecated
|
||||||
|
* features that were encountered during validation.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
protected $warnings = array();
|
protected $warnings = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a critical validation problem is encountered, this will be
|
||||||
|
* set to the value of one of this class's ERR_* constants.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
protected $error;
|
protected $error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
protected $threshold = 255;
|
protected $threshold = 255;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
@@ -73,6 +112,9 @@ class EmailValidator
|
|||||||
$this->parser = new EmailParser(new EmailLexer());
|
$this->parser = new EmailParser(new EmailLexer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
public function isValid($email, $checkDNS = false, $strict = false)
|
public function isValid($email, $checkDNS = false, $strict = false)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -84,22 +126,18 @@ class EmailValidator
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dns = true;
|
$dnsProblemExists = ($checkDNS ? !$this->checkDNS() : false);
|
||||||
if ($checkDNS) {
|
|
||||||
$dns = $this->checkDNS();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->hasWarnings() && ((int) max($this->warnings) > $this->threshold)) {
|
if ($this->hasWarnings() && ((int) max($this->warnings) > $this->threshold)) {
|
||||||
$this->error = self::ERR_DEPREC_REACHED;
|
$this->error = self::ERR_DEPREC_REACHED;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !$strict || (!$this->hasWarnings() && $dns);
|
return !($dnsProblemExists || $strict && $this->hasWarnings());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function hasWarnings()
|
public function hasWarnings()
|
||||||
{
|
{
|
||||||
@@ -107,7 +145,7 @@ class EmailValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function getWarnings()
|
public function getWarnings()
|
||||||
{
|
{
|
||||||
@@ -115,7 +153,7 @@ class EmailValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function getError()
|
public function getError()
|
||||||
{
|
{
|
||||||
@@ -123,9 +161,7 @@ class EmailValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $threshold
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @return EmailValidator
|
|
||||||
*/
|
*/
|
||||||
public function setThreshold($threshold)
|
public function setThreshold($threshold)
|
||||||
{
|
{
|
||||||
@@ -135,26 +171,30 @@ class EmailValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function getThreshold()
|
public function getThreshold()
|
||||||
{
|
{
|
||||||
return $this->threshold;
|
return $this->threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool Whether or not an MX record exists for the
|
||||||
|
* email address's host name.
|
||||||
|
*/
|
||||||
protected function checkDNS()
|
protected function checkDNS()
|
||||||
{
|
{
|
||||||
$checked = true;
|
$host = $this->parser->getParsedDomainPart();
|
||||||
|
$host = rtrim($host, '.') . '.';
|
||||||
|
|
||||||
$result = checkdnsrr(trim($this->parser->getParsedDomainPart()), 'MX');
|
$mxRecordExists = checkdnsrr($host, 'MX');
|
||||||
|
|
||||||
if (!$result) {
|
if (!$mxRecordExists) {
|
||||||
$this->warnings[] = self::DNSWARN_NO_RECORD;
|
$this->warnings[] = self::DNSWARN_NO_RECORD;
|
||||||
$checked = false;
|
|
||||||
$this->addTLDWarnings();
|
$this->addTLDWarnings();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $checked;
|
return $mxRecordExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function addTLDWarnings()
|
protected function addTLDWarnings()
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Egulias\EmailValidator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EmailValidatorInterface
|
||||||
|
*
|
||||||
|
* @author Chris McCafferty <cilefen@gmail.com>
|
||||||
|
*/
|
||||||
|
interface EmailValidatorInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Validates an email address against the following standards:
|
||||||
|
*
|
||||||
|
* RFC-5321: Simple Mail Transfer Protocol
|
||||||
|
* RFC-5322: Internet Message Format
|
||||||
|
* RFC-6530: Overview and Framework for Internationalized Email
|
||||||
|
* RFC-6531: SMTP Extension for Internationalized Email
|
||||||
|
* RFC-6532: Internationalized Email Headers
|
||||||
|
* RFC-1123 section 2.1: Requirements for Internet Hosts -- Application and Support
|
||||||
|
* RFC-4291 section 2.2: IP Version 6 Addressing Architecture
|
||||||
|
*
|
||||||
|
* @param string $email The email address to validate.
|
||||||
|
* @param bool $checkDNS Whether or not the email address's hostname should
|
||||||
|
* be confirmed with a DNS lookup. This only comes
|
||||||
|
* into play if strict mode is also enabled.
|
||||||
|
* @param bool $strict If this is true, and any informational warnings
|
||||||
|
* were raised during validation, the email address
|
||||||
|
* will be considered invalid. Additionally, if
|
||||||
|
* $checkDNS is true and the DNS lookup failed,
|
||||||
|
* the email address will be considered invalid.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isValid($email, $checkDNS = false, $strict = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasWarnings();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getWarnings();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getError();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $threshold The acceptable number of deprecation warnings.
|
||||||
|
*
|
||||||
|
* @return EmailValidator
|
||||||
|
*/
|
||||||
|
public function setThreshold($threshold);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getThreshold();
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
namespace Egulias\EmailValidator\Parser;
|
namespace Egulias\EmailValidator\Parser;
|
||||||
|
|
||||||
use Egulias\EmailValidator\EmailLexer;
|
use Egulias\EmailValidator\EmailLexer;
|
||||||
use Egulias\EmailValidator\Parser\Parser;
|
|
||||||
use Egulias\EmailValidator\EmailValidator;
|
use Egulias\EmailValidator\EmailValidator;
|
||||||
|
|
||||||
class DomainPart extends Parser
|
class DomainPart extends Parser
|
||||||
@@ -103,26 +102,34 @@ class DomainPart extends Parser
|
|||||||
protected function doParseDomainPart()
|
protected function doParseDomainPart()
|
||||||
{
|
{
|
||||||
$domain = '';
|
$domain = '';
|
||||||
|
$openedParenthesis = 0;
|
||||||
|
$openBrackets = false;
|
||||||
do {
|
do {
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_SEMICOLON) {
|
|
||||||
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
|
||||||
}
|
|
||||||
|
|
||||||
$prev = $this->lexer->getPrevious();
|
$prev = $this->lexer->getPrevious();
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_SLASH) {
|
$this->checkNotAllowedChars($this->lexer->token);
|
||||||
throw new \InvalidArgumentException('ERR_DOMAIN_CHAR_NOT_ALLOWED');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
||||||
$this->parseComments();
|
$this->parseComments();
|
||||||
|
$openedParenthesis += $this->getOpenedParenthesis();
|
||||||
$this->lexer->moveNext();
|
$this->lexer->moveNext();
|
||||||
|
$tmpPrev = $this->lexer->getPrevious();
|
||||||
|
if ($tmpPrev['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
|
||||||
|
$openedParenthesis--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
|
||||||
|
if ($openedParenthesis === 0) {
|
||||||
|
throw new \InvalidArgumentException('ERR_UNOPENEDCOMMENT');
|
||||||
|
} else {
|
||||||
|
$openedParenthesis--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkConsecutiveDots();
|
$this->checkConsecutiveDots();
|
||||||
$this->checkDomainPartExceptions($prev);
|
$this->checkDomainPartExceptions($prev);
|
||||||
|
|
||||||
if ($this->hasBrackets()) {
|
if ($openBrackets = $this->hasBrackets($openBrackets)) {
|
||||||
$this->parseDomainLiteral();
|
$this->parseDomainLiteral();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,11 +141,19 @@ class DomainPart extends Parser
|
|||||||
|
|
||||||
$domain .= $this->lexer->token['value'];
|
$domain .= $this->lexer->token['value'];
|
||||||
$this->lexer->moveNext();
|
$this->lexer->moveNext();
|
||||||
} while ($this->lexer->token);
|
} while (null !== $this->lexer->token['type']);
|
||||||
|
|
||||||
return $domain;
|
return $domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function checkNotAllowedChars($token)
|
||||||
|
{
|
||||||
|
$notAllowed = array(EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true);
|
||||||
|
if (isset($notAllowed[$token['type']])) {
|
||||||
|
throw new \InvalidArgumentException('ERR_DOMAIN_CHAR_NOT_ALLOWED');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected function parseDomainLiteral()
|
protected function parseDomainLiteral()
|
||||||
{
|
{
|
||||||
if ($this->lexer->isNextToken(EmailLexer::S_COLON)) {
|
if ($this->lexer->isNextToken(EmailLexer::S_COLON)) {
|
||||||
@@ -183,7 +198,7 @@ class DomainPart extends Parser
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->lexer->isNextToken(EmailLexer::S_CR)) {
|
if ($this->lexer->isNextToken(EmailLexer::S_CR)) {
|
||||||
throw new \InvalidArgumentException("ERR_CR_NO_LF");
|
throw new \InvalidArgumentException('ERR_CR_NO_LF');
|
||||||
}
|
}
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) {
|
if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) {
|
||||||
$this->warnings[] = EmailValidator::RFC5322_DOMLIT_OBSDTEXT;
|
$this->warnings[] = EmailValidator::RFC5322_DOMLIT_OBSDTEXT;
|
||||||
@@ -221,9 +236,6 @@ class DomainPart extends Parser
|
|||||||
return $addressLiteral;
|
return $addressLiteral;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $addressLiteral
|
|
||||||
*/
|
|
||||||
protected function checkIPV4Tag($addressLiteral)
|
protected function checkIPV4Tag($addressLiteral)
|
||||||
{
|
{
|
||||||
$matchesIP = array();
|
$matchesIP = array();
|
||||||
@@ -249,6 +261,17 @@ class DomainPart extends Parser
|
|||||||
|
|
||||||
protected function checkDomainPartExceptions($prev)
|
protected function checkDomainPartExceptions($prev)
|
||||||
{
|
{
|
||||||
|
$invalidDomainTokens = array(
|
||||||
|
EmailLexer::S_DQUOTE => true,
|
||||||
|
EmailLexer::S_SEMICOLON => true,
|
||||||
|
EmailLexer::S_GREATERTHAN => true,
|
||||||
|
EmailLexer::S_LOWERTHAN => true,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($invalidDomainTokens[$this->lexer->token['type']])) {
|
||||||
|
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_COMMA) {
|
if ($this->lexer->token['type'] === EmailLexer::S_COMMA) {
|
||||||
throw new \InvalidArgumentException('ERR_COMMA_IN_DOMAIN');
|
throw new \InvalidArgumentException('ERR_COMMA_IN_DOMAIN');
|
||||||
}
|
}
|
||||||
@@ -271,8 +294,12 @@ class DomainPart extends Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function hasBrackets()
|
protected function hasBrackets($openBrackets)
|
||||||
{
|
{
|
||||||
|
if ($this->lexer->token['type'] === EmailLexer::S_CLOSEBRACKET && !$openBrackets) {
|
||||||
|
throw new \InvalidArgumentException('ERR_EXPECTING_OPENBRACKET');
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) {
|
if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ namespace Egulias\EmailValidator\Parser;
|
|||||||
|
|
||||||
use Egulias\EmailValidator\EmailLexer;
|
use Egulias\EmailValidator\EmailLexer;
|
||||||
use Egulias\EmailValidator\EmailValidator;
|
use Egulias\EmailValidator\EmailValidator;
|
||||||
use \InvalidArgumentException;
|
|
||||||
|
|
||||||
class LocalPart extends Parser
|
class LocalPart extends Parser
|
||||||
{
|
{
|
||||||
@@ -12,11 +11,14 @@ class LocalPart extends Parser
|
|||||||
{
|
{
|
||||||
$parseDQuote = true;
|
$parseDQuote = true;
|
||||||
$closingQuote = false;
|
$closingQuote = false;
|
||||||
|
$openedParenthesis = 0;
|
||||||
|
|
||||||
while ($this->lexer->token['type'] !== EmailLexer::S_AT && $this->lexer->token) {
|
while ($this->lexer->token['type'] !== EmailLexer::S_AT && null !== $this->lexer->token['type']) {
|
||||||
|
if ($this->lexer->token['type'] === EmailLexer::S_DOT) {
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_DOT && !$this->lexer->getPrevious()) {
|
$previous = $this->lexer->getPrevious();
|
||||||
throw new \InvalidArgumentException('ERR_DOT_START');
|
if (null === $previous['type']) {
|
||||||
|
throw new \InvalidArgumentException('ERR_DOT_START');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$closingQuote = $this->checkDQUOTE($closingQuote);
|
$closingQuote = $this->checkDQUOTE($closingQuote);
|
||||||
@@ -26,12 +28,19 @@ class LocalPart extends Parser
|
|||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
|
||||||
$this->parseComments();
|
$this->parseComments();
|
||||||
|
$openedParenthesis += $this->getOpenedParenthesis();
|
||||||
|
}
|
||||||
|
if ($this->lexer->token['type'] === EmailLexer::S_CLOSEPARENTHESIS) {
|
||||||
|
if ($openedParenthesis === 0) {
|
||||||
|
throw new \InvalidArgumentException('ERR_UNOPENEDCOMMENT');
|
||||||
|
} else {
|
||||||
|
$openedParenthesis--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkConsecutiveDots();
|
$this->checkConsecutiveDots();
|
||||||
|
|
||||||
if (
|
if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
|
||||||
$this->lexer->token['type'] === EmailLexer::S_DOT &&
|
|
||||||
$this->lexer->isNextToken(EmailLexer::S_AT)
|
$this->lexer->isNextToken(EmailLexer::S_AT)
|
||||||
) {
|
) {
|
||||||
throw new \InvalidArgumentException('ERR_DOT_END');
|
throw new \InvalidArgumentException('ERR_DOT_END');
|
||||||
@@ -72,7 +81,7 @@ class LocalPart extends Parser
|
|||||||
|
|
||||||
$this->lexer->moveNext();
|
$this->lexer->moveNext();
|
||||||
|
|
||||||
while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && $this->lexer->token) {
|
while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && null !== $this->lexer->token['type']) {
|
||||||
$parseAgain = false;
|
$parseAgain = false;
|
||||||
if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
|
if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
|
||||||
$this->warnings[] = EmailValidator::CFWS_FWS;
|
$this->warnings[] = EmailValidator::CFWS_FWS;
|
||||||
@@ -82,7 +91,7 @@ class LocalPart extends Parser
|
|||||||
$this->lexer->moveNext();
|
$this->lexer->moveNext();
|
||||||
|
|
||||||
if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) {
|
if (!$this->escaped() && isset($invalid[$this->lexer->token['type']])) {
|
||||||
throw new InvalidArgumentException("ERR_EXPECTED_ATEXT");
|
throw new \InvalidArgumentException('ERR_EXPECTED_ATEXT');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,12 +99,12 @@ class LocalPart extends Parser
|
|||||||
|
|
||||||
if ($prev['type'] === EmailLexer::S_BACKSLASH) {
|
if ($prev['type'] === EmailLexer::S_BACKSLASH) {
|
||||||
if (!$this->checkDQUOTE(false)) {
|
if (!$this->checkDQUOTE(false)) {
|
||||||
throw new \InvalidArgumentException("ERR_UNCLOSED_DQUOTE");
|
throw new \InvalidArgumentException('ERR_UNCLOSED_DQUOTE');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) {
|
if (!$this->lexer->isNextToken(EmailLexer::S_AT) && $prev['type'] !== EmailLexer::S_BACKSLASH) {
|
||||||
throw new \InvalidArgumentException("ERR_EXPECED_AT");
|
throw new \InvalidArgumentException('ERR_EXPECED_AT');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $parseAgain;
|
return $parseAgain;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ abstract class Parser
|
|||||||
{
|
{
|
||||||
protected $warnings = array();
|
protected $warnings = array();
|
||||||
protected $lexer;
|
protected $lexer;
|
||||||
|
protected $openedParenthesis = 0;
|
||||||
|
|
||||||
public function __construct(EmailLexer $lexer)
|
public function __construct(EmailLexer $lexer)
|
||||||
{
|
{
|
||||||
@@ -20,7 +21,13 @@ abstract class Parser
|
|||||||
return $this->warnings;
|
return $this->warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract function parse($str);
|
abstract public function parse($str);
|
||||||
|
|
||||||
|
/** @return int */
|
||||||
|
public function getOpenedParenthesis()
|
||||||
|
{
|
||||||
|
return $this->openedParenthesis;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* validateQuotedPair
|
* validateQuotedPair
|
||||||
@@ -35,15 +42,15 @@ abstract class Parser
|
|||||||
$this->warnings[] = EmailValidator::DEPREC_QP;
|
$this->warnings[] = EmailValidator::DEPREC_QP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string the the comment
|
|
||||||
* @throws \InvalidArgumentException
|
|
||||||
*/
|
|
||||||
protected function parseComments()
|
protected function parseComments()
|
||||||
{
|
{
|
||||||
|
$this->openedParenthesis = 1;
|
||||||
$this->isUnclosedComment();
|
$this->isUnclosedComment();
|
||||||
$this->warnings[] = EmailValidator::CFWS_COMMENT;
|
$this->warnings[] = EmailValidator::CFWS_COMMENT;
|
||||||
while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) {
|
while (!$this->lexer->isNextToken(EmailLexer::S_CLOSEPARENTHESIS)) {
|
||||||
|
if ($this->lexer->isNextToken(EmailLexer::S_OPENPARENTHESIS)) {
|
||||||
|
$this->openedParenthesis++;
|
||||||
|
}
|
||||||
$this->warnEscaping();
|
$this->warnEscaping();
|
||||||
$this->lexer->moveNext();
|
$this->lexer->moveNext();
|
||||||
}
|
}
|
||||||
@@ -75,11 +82,11 @@ abstract class Parser
|
|||||||
$this->checkCRLFInFWS();
|
$this->checkCRLFInFWS();
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_CR) {
|
if ($this->lexer->token['type'] === EmailLexer::S_CR) {
|
||||||
throw new \InvalidArgumentException("ERR_CR_NO_LF");
|
throw new \InvalidArgumentException('ERR_CR_NO_LF');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] !== EmailLexer::S_AT) {
|
if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] !== EmailLexer::S_AT) {
|
||||||
throw new \InvalidArgumentException("ERR_ATEXT_AFTER_CFWS");
|
throw new \InvalidArgumentException('ERR_ATEXT_AFTER_CFWS');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_LF || $this->lexer->token['type'] === EmailLexer::C_NUL) {
|
if ($this->lexer->token['type'] === EmailLexer::S_LF || $this->lexer->token['type'] === EmailLexer::C_NUL) {
|
||||||
@@ -160,7 +167,7 @@ abstract class Parser
|
|||||||
return $hasClosingQuote;
|
return $hasClosingQuote;
|
||||||
}
|
}
|
||||||
$previous = $this->lexer->getPrevious();
|
$previous = $this->lexer->getPrevious();
|
||||||
if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous['type'] === EmailLexer::GENERIC) {
|
if ($previous['type'] === EmailLexer::GENERIC && $this->lexer->isNextToken(EmailLexer::GENERIC)) {
|
||||||
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
throw new \InvalidArgumentException('ERR_EXPECTING_ATEXT');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,10 +188,10 @@ abstract class Parser
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($this->lexer->isNextToken(EmailLexer::CRLF)) {
|
if ($this->lexer->isNextToken(EmailLexer::CRLF)) {
|
||||||
throw new \InvalidArgumentException("ERR_FWS_CRLF_X2");
|
throw new \InvalidArgumentException('ERR_FWS_CRLF_X2');
|
||||||
}
|
}
|
||||||
if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) {
|
if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB))) {
|
||||||
throw new \InvalidArgumentException("ERR_FWS_CRLF_END");
|
throw new \InvalidArgumentException('ERR_FWS_CRLF_END');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
namespace Egulias\EmailValidator\Tests;
|
namespace Egulias\EmailValidator\Tests;
|
||||||
|
|
||||||
use Egulias\EmailValidator\EmailLexer;
|
use Egulias\EmailValidator\EmailLexer;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class EmailLexerTests extends \PHPUnit_Framework_TestCase
|
class EmailLexerTests extends TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
public function testLexerExtendsLib()
|
public function testLexerExtendsLib()
|
||||||
@@ -103,6 +104,17 @@ class EmailLexerTests extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals(EmailLexer::S_HTAB, $lexer->token['type']);
|
$this->assertEquals(EmailLexer::S_HTAB, $lexer->token['type']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testLexerForUTF8()
|
||||||
|
{
|
||||||
|
$lexer = new EmailLexer();
|
||||||
|
$lexer->setInput("áÇ@bar.com");
|
||||||
|
$lexer->moveNext();
|
||||||
|
$lexer->moveNext();
|
||||||
|
$this->assertEquals(EmailLexer::GENERIC, $lexer->token['type']);
|
||||||
|
$lexer->moveNext();
|
||||||
|
$this->assertEquals(EmailLexer::GENERIC, $lexer->token['type']);
|
||||||
|
}
|
||||||
|
|
||||||
public function testLexerSearchToken()
|
public function testLexerSearchToken()
|
||||||
{
|
{
|
||||||
$lexer = new EmailLexer();
|
$lexer = new EmailLexer();
|
||||||
@@ -111,15 +123,6 @@ class EmailLexerTests extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertTrue($lexer->find(EmailLexer::S_HTAB));
|
$this->assertTrue($lexer->find(EmailLexer::S_HTAB));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLexerHasInvalidTokens()
|
|
||||||
{
|
|
||||||
$lexer = new EmailLexer();
|
|
||||||
$lexer->setInput(chr(226));
|
|
||||||
$lexer->moveNext();
|
|
||||||
$lexer->moveNext();
|
|
||||||
$this->assertTrue($lexer->hasInvalidTokens());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTokens()
|
public function getTokens()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
@@ -152,7 +155,7 @@ class EmailLexerTests extends \PHPUnit_Framework_TestCase
|
|||||||
array('}', EmailLexer::S_CLOSEQBRACKET),
|
array('}', EmailLexer::S_CLOSEQBRACKET),
|
||||||
array('', EmailLexer::S_EMPTY),
|
array('', EmailLexer::S_EMPTY),
|
||||||
array(chr(31), EmailLexer::INVALID),
|
array(chr(31), EmailLexer::INVALID),
|
||||||
array(chr(226), EmailLexer::INVALID),
|
array(chr(226), EmailLexer::GENERIC),
|
||||||
array(chr(0), EmailLexer::C_NUL)
|
array(chr(0), EmailLexer::C_NUL)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
namespace Egulias\Tests\EmailValidator;
|
namespace Egulias\Tests\EmailValidator;
|
||||||
|
|
||||||
use Egulias\EmailValidator\EmailValidator;
|
use Egulias\EmailValidator\EmailValidator;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
class EmailValidatorTest extends TestCase
|
||||||
{
|
{
|
||||||
protected $validator;
|
protected $validator;
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
public function getValidEmails()
|
public function getValidEmails()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
|
array('â@iana.org'),
|
||||||
array('fabien@symfony.com'),
|
array('fabien@symfony.com'),
|
||||||
array('example@example.co.uk'),
|
array('example@example.co.uk'),
|
||||||
array('fabien_potencier@example.fr'),
|
array('fabien_potencier@example.fr'),
|
||||||
@@ -55,6 +57,15 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
array('"test\ test"@iana.org'),
|
array('"test\ test"@iana.org'),
|
||||||
array('""@iana.org'),
|
array('""@iana.org'),
|
||||||
array('"\""@iana.org'),
|
array('"\""@iana.org'),
|
||||||
|
array('müller@möller.de'),
|
||||||
|
array('test@email*'),
|
||||||
|
array('test@email!'),
|
||||||
|
array('test@email&'),
|
||||||
|
array('test@email^'),
|
||||||
|
array('test@email%'),
|
||||||
|
array('test@email$'),
|
||||||
|
array('test@email.com.au'),
|
||||||
|
array('1500111@профи-инвест.рф'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +80,7 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
public function getInvalidEmails()
|
public function getInvalidEmails()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
|
array('test@example.com test'),
|
||||||
array('user name@example.com'),
|
array('user name@example.com'),
|
||||||
array('user name@example.com'),
|
array('user name@example.com'),
|
||||||
array('example.@example.co.uk'),
|
array('example.@example.co.uk'),
|
||||||
@@ -79,6 +90,7 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
array('.example@localhost'),
|
array('.example@localhost'),
|
||||||
array('ex\ample@localhost'),
|
array('ex\ample@localhost'),
|
||||||
array('example@local\host'),
|
array('example@local\host'),
|
||||||
|
array('example@localhost\\'),
|
||||||
array('example@localhost.'),
|
array('example@localhost.'),
|
||||||
array('user name@example.com'),
|
array('user name@example.com'),
|
||||||
array('username@ example . com'),
|
array('username@ example . com'),
|
||||||
@@ -109,6 +121,14 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
array('test@iana.org \r\n\r\n '),
|
array('test@iana.org \r\n\r\n '),
|
||||||
array('test@iana/icann.org'),
|
array('test@iana/icann.org'),
|
||||||
array('test@foo;bar.com'),
|
array('test@foo;bar.com'),
|
||||||
|
array('test;123@foobar.com'),
|
||||||
|
array('test@example..com'),
|
||||||
|
array('email.email@email."'),
|
||||||
|
array('test@email>'),
|
||||||
|
array('test@email<'),
|
||||||
|
array('test@email{'),
|
||||||
|
array('test@email.com]'),
|
||||||
|
array('test@ema[il.com'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +158,11 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
array(EmailValidator::ERR_DOT_END, 'example@localhost.'),
|
array(EmailValidator::ERR_DOT_END, 'example@localhost.'),
|
||||||
array(EmailValidator::ERR_DOT_END, 'example.@example.co.uk'),
|
array(EmailValidator::ERR_DOT_END, 'example.@example.co.uk'),
|
||||||
array(EmailValidator::ERR_UNCLOSEDCOMMENT, '(example@localhost'),
|
array(EmailValidator::ERR_UNCLOSEDCOMMENT, '(example@localhost'),
|
||||||
|
array(EmailValidator::ERR_UNOPENEDCOMMENT, 'comment)example@localhost'),
|
||||||
|
array(EmailValidator::ERR_UNOPENEDCOMMENT, 'example(comment))@localhost'),
|
||||||
|
array(EmailValidator::ERR_UNOPENEDCOMMENT, 'example@comment)localhost'),
|
||||||
|
array(EmailValidator::ERR_UNOPENEDCOMMENT, 'example@localhost(comment))'),
|
||||||
|
array(EmailValidator::ERR_UNOPENEDCOMMENT, 'example@(comment))example.com'),
|
||||||
array(EmailValidator::ERR_UNCLOSEDQUOTEDSTR, '"example@localhost'),
|
array(EmailValidator::ERR_UNCLOSEDQUOTEDSTR, '"example@localhost'),
|
||||||
array(EmailValidator::ERR_EXPECTING_ATEXT, 'exa"mple@localhost'),
|
array(EmailValidator::ERR_EXPECTING_ATEXT, 'exa"mple@localhost'),
|
||||||
//This was the original. But atext is not allowed after \n
|
//This was the original. But atext is not allowed after \n
|
||||||
@@ -156,7 +181,7 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
*/
|
*/
|
||||||
public function testValidEmailsWithWarningsCheck($warnings, $email)
|
public function testValidEmailsWithWarningsCheck($warnings, $email)
|
||||||
{
|
{
|
||||||
$this->assertTrue($this->validator->isValid($email, true));
|
$this->assertFalse($this->validator->isValid($email, true));
|
||||||
|
|
||||||
$this->assertEquals($warnings, $this->validator->getWarnings());
|
$this->assertEquals($warnings, $this->validator->getWarnings());
|
||||||
}
|
}
|
||||||
@@ -179,21 +204,21 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
EmailValidator::DEPREC_CFWS_NEAR_AT,
|
EmailValidator::DEPREC_CFWS_NEAR_AT,
|
||||||
EmailValidator::DNSWARN_NO_RECORD
|
EmailValidator::DNSWARN_NO_RECORD
|
||||||
),
|
),
|
||||||
'example @example.co.uk'
|
'example @invalid.example.com'
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
EmailValidator::DEPREC_CFWS_NEAR_AT,
|
EmailValidator::DEPREC_CFWS_NEAR_AT,
|
||||||
EmailValidator::DNSWARN_NO_RECORD
|
EmailValidator::DNSWARN_NO_RECORD
|
||||||
),
|
),
|
||||||
'example@ example.co.uk'
|
'example@ invalid.example.com'
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
EmailValidator::CFWS_COMMENT,
|
EmailValidator::CFWS_COMMENT,
|
||||||
EmailValidator::DNSWARN_NO_RECORD
|
EmailValidator::DNSWARN_NO_RECORD
|
||||||
),
|
),
|
||||||
'example@example(examplecomment).co.uk'
|
'example@invalid.example(examplecomment).com'
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
@@ -201,7 +226,7 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
EmailValidator::DEPREC_CFWS_NEAR_AT,
|
EmailValidator::DEPREC_CFWS_NEAR_AT,
|
||||||
EmailValidator::DNSWARN_NO_RECORD,
|
EmailValidator::DNSWARN_NO_RECORD,
|
||||||
),
|
),
|
||||||
'example(examplecomment)@example.co.uk'
|
'example(examplecomment)@invalid.example.com'
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
@@ -209,7 +234,7 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
EmailValidator::CFWS_FWS,
|
EmailValidator::CFWS_FWS,
|
||||||
EmailValidator::DNSWARN_NO_RECORD,
|
EmailValidator::DNSWARN_NO_RECORD,
|
||||||
),
|
),
|
||||||
"\"\t\"@example.co.uk"
|
"\"\t\"@invalid.example.com"
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
@@ -217,7 +242,7 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
EmailValidator::CFWS_FWS,
|
EmailValidator::CFWS_FWS,
|
||||||
EmailValidator::DNSWARN_NO_RECORD
|
EmailValidator::DNSWARN_NO_RECORD
|
||||||
),
|
),
|
||||||
"\"\r\"@example.co.uk"
|
"\"\r\"@invalid.example.com"
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
@@ -309,14 +334,14 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
EmailValidator::RFC5321_QUOTEDSTRING,
|
EmailValidator::RFC5321_QUOTEDSTRING,
|
||||||
EmailValidator::DNSWARN_NO_RECORD
|
EmailValidator::DNSWARN_NO_RECORD
|
||||||
),
|
),
|
||||||
'"example"@example.co.uk'
|
'"example"@invalid.example.com'
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
EmailValidator::RFC5322_LOCAL_TOOLONG,
|
EmailValidator::RFC5322_LOCAL_TOOLONG,
|
||||||
EmailValidator::DNSWARN_NO_RECORD
|
EmailValidator::DNSWARN_NO_RECORD
|
||||||
),
|
),
|
||||||
'too_long_localpart_too_long_localpart_too_long_localpart_too_long_localpart@example.co.uk'
|
'too_long_localpart_too_long_localpart_too_long_localpart_too_long_localpart@invalid.example.com'
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
array(
|
array(
|
||||||
|
|||||||
Reference in New Issue
Block a user