Add NormEmail
This commit is contained in:
parent
f04dc6f280
commit
2b5a996578
11 changed files with 464 additions and 20 deletions
|
@ -4,6 +4,7 @@
|
||||||
"homepage": "https://github.com/forkbb",
|
"homepage": "https://github.com/forkbb",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"minimum-stability": "dev",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Visman",
|
"name": "Visman",
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
"ext-gd": "*",
|
"ext-gd": "*",
|
||||||
"ext-mbstring": "*",
|
"ext-mbstring": "*",
|
||||||
"artoodetoo/dirk": "dev-visman",
|
"artoodetoo/dirk": "dev-visman",
|
||||||
"miovisman/parserus": "dev-master"
|
"miovisman/parserus": "dev-master",
|
||||||
|
"miovisman/normemail": "dev-master"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
60
composer.lock
generated
60
composer.lock
generated
|
@ -1,11 +1,10 @@
|
||||||
{
|
{
|
||||||
"_readme": [
|
"_readme": [
|
||||||
"This file locks the dependencies of your project to a known state",
|
"This file locks the dependencies of your project to a known state",
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "533b558f4bef9f6e04f96421dd776ab4",
|
"content-hash": "dd233d78a2c422cc3c940a860acb6b41",
|
||||||
"content-hash": "6646dc09855f04f546d6d92253e01a30",
|
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "artoodetoo/dirk",
|
"name": "artoodetoo/dirk",
|
||||||
|
@ -58,7 +57,53 @@
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/MioVisman/dirk/tree/visman"
|
"source": "https://github.com/MioVisman/dirk/tree/visman"
|
||||||
},
|
},
|
||||||
"time": "2019-11-28 13:14:33"
|
"time": "2019-11-28T13:14:33+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "miovisman/normemail",
|
||||||
|
"version": "dev-master",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MioVisman/NormEmail.git",
|
||||||
|
"reference": "c582b1359adf1ee2efa38809e8827ed21138a9ac"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MioVisman/NormEmail/zipball/c582b1359adf1ee2efa38809e8827ed21138a9ac",
|
||||||
|
"reference": "c582b1359adf1ee2efa38809e8827ed21138a9ac",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-intl": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": ">=5.6.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"MioVisman\\NormEmail\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Visman",
|
||||||
|
"email": "mio.visman@yandex.ru",
|
||||||
|
"homepage": "https://github.com/MioVisman"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Normalization of email for bans, for request cache to SFS or for checking the uniqueness of new users.",
|
||||||
|
"homepage": "https://github.com/MioVisman/NormEmail",
|
||||||
|
"keywords": [
|
||||||
|
"ban",
|
||||||
|
"canonical email",
|
||||||
|
"email",
|
||||||
|
"normalization"
|
||||||
|
],
|
||||||
|
"time": "2019-12-24T15:42:43+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "miovisman/parserus",
|
"name": "miovisman/parserus",
|
||||||
|
@ -100,15 +145,16 @@
|
||||||
"bbcode",
|
"bbcode",
|
||||||
"parser"
|
"parser"
|
||||||
],
|
],
|
||||||
"time": "2019-10-11 12:06:27"
|
"time": "2019-10-11T12:06:27+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [],
|
"packages-dev": [],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "dev",
|
||||||
"stability-flags": {
|
"stability-flags": {
|
||||||
"artoodetoo/dirk": 20,
|
"artoodetoo/dirk": 20,
|
||||||
"miovisman/parserus": 20
|
"miovisman/parserus": 20,
|
||||||
|
"miovisman/normemail": 20
|
||||||
},
|
},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
|
|
48
vendor/composer/ClassLoader.php
vendored
48
vendor/composer/ClassLoader.php
vendored
|
@ -55,6 +55,7 @@ class ClassLoader
|
||||||
private $classMap = array();
|
private $classMap = array();
|
||||||
private $classMapAuthoritative = false;
|
private $classMapAuthoritative = false;
|
||||||
private $missingClasses = array();
|
private $missingClasses = array();
|
||||||
|
private $apcuPrefix;
|
||||||
|
|
||||||
public function getPrefixes()
|
public function getPrefixes()
|
||||||
{
|
{
|
||||||
|
@ -271,6 +272,26 @@ class ClassLoader
|
||||||
return $this->classMapAuthoritative;
|
return $this->classMapAuthoritative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||||
|
*
|
||||||
|
* @param string|null $apcuPrefix
|
||||||
|
*/
|
||||||
|
public function setApcuPrefix($apcuPrefix)
|
||||||
|
{
|
||||||
|
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getApcuPrefix()
|
||||||
|
{
|
||||||
|
return $this->apcuPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers this instance as an autoloader.
|
* Registers this instance as an autoloader.
|
||||||
*
|
*
|
||||||
|
@ -313,11 +334,6 @@ class ClassLoader
|
||||||
*/
|
*/
|
||||||
public function findFile($class)
|
public function findFile($class)
|
||||||
{
|
{
|
||||||
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
|
|
||||||
if ('\\' == $class[0]) {
|
|
||||||
$class = substr($class, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// class map lookup
|
// class map lookup
|
||||||
if (isset($this->classMap[$class])) {
|
if (isset($this->classMap[$class])) {
|
||||||
return $this->classMap[$class];
|
return $this->classMap[$class];
|
||||||
|
@ -325,6 +341,12 @@ class ClassLoader
|
||||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (null !== $this->apcuPrefix) {
|
||||||
|
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||||
|
if ($hit) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$file = $this->findFileWithExtension($class, '.php');
|
$file = $this->findFileWithExtension($class, '.php');
|
||||||
|
|
||||||
|
@ -333,6 +355,10 @@ class ClassLoader
|
||||||
$file = $this->findFileWithExtension($class, '.hh');
|
$file = $this->findFileWithExtension($class, '.hh');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null !== $this->apcuPrefix) {
|
||||||
|
apcu_add($this->apcuPrefix.$class, $file);
|
||||||
|
}
|
||||||
|
|
||||||
if (false === $file) {
|
if (false === $file) {
|
||||||
// Remember that this class does not exist.
|
// Remember that this class does not exist.
|
||||||
$this->missingClasses[$class] = true;
|
$this->missingClasses[$class] = true;
|
||||||
|
@ -348,10 +374,14 @@ class ClassLoader
|
||||||
|
|
||||||
$first = $class[0];
|
$first = $class[0];
|
||||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||||
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
|
$subPath = $class;
|
||||||
if (0 === strpos($class, $prefix)) {
|
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||||
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
|
$subPath = substr($subPath, 0, $lastPos);
|
||||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
|
$search = $subPath . '\\';
|
||||||
|
if (isset($this->prefixDirsPsr4[$search])) {
|
||||||
|
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||||
|
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||||
|
if (file_exists($file = $dir . $pathEnd)) {
|
||||||
return $file;
|
return $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
vendor/composer/LICENSE
vendored
2
vendor/composer/LICENSE
vendored
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
Copyright (c) 2016 Nils Adermann, Jordi Boggiano
|
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
1
vendor/composer/autoload_psr4.php
vendored
1
vendor/composer/autoload_psr4.php
vendored
|
@ -7,5 +7,6 @@ $baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'R2\\Templating\\' => array($vendorDir . '/artoodetoo/dirk/src'),
|
'R2\\Templating\\' => array($vendorDir . '/artoodetoo/dirk/src'),
|
||||||
|
'MioVisman\\NormEmail\\' => array($vendorDir . '/miovisman/normemail/src'),
|
||||||
'ForkBB\\' => array($baseDir . '/app'),
|
'ForkBB\\' => array($baseDir . '/app'),
|
||||||
);
|
);
|
||||||
|
|
8
vendor/composer/autoload_static.php
vendored
8
vendor/composer/autoload_static.php
vendored
|
@ -11,6 +11,10 @@ class ComposerStaticInit90ad93c7251d4f60daa9e545879c49e7
|
||||||
array (
|
array (
|
||||||
'R2\\Templating\\' => 14,
|
'R2\\Templating\\' => 14,
|
||||||
),
|
),
|
||||||
|
'M' =>
|
||||||
|
array (
|
||||||
|
'MioVisman\\NormEmail\\' => 20,
|
||||||
|
),
|
||||||
'F' =>
|
'F' =>
|
||||||
array (
|
array (
|
||||||
'ForkBB\\' => 7,
|
'ForkBB\\' => 7,
|
||||||
|
@ -22,6 +26,10 @@ class ComposerStaticInit90ad93c7251d4f60daa9e545879c49e7
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/artoodetoo/dirk/src',
|
0 => __DIR__ . '/..' . '/artoodetoo/dirk/src',
|
||||||
),
|
),
|
||||||
|
'MioVisman\\NormEmail\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/miovisman/normemail/src',
|
||||||
|
),
|
||||||
'ForkBB\\' =>
|
'ForkBB\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/../..' . '/app',
|
0 => __DIR__ . '/../..' . '/app',
|
||||||
|
|
52
vendor/composer/installed.json
vendored
52
vendor/composer/installed.json
vendored
|
@ -20,7 +20,7 @@
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "4.0.*"
|
"phpunit/phpunit": "4.0.*"
|
||||||
},
|
},
|
||||||
"time": "2019-11-28 13:14:33",
|
"time": "2019-11-28T13:14:33+00:00",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"installation-source": "dist",
|
"installation-source": "dist",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -54,6 +54,54 @@
|
||||||
"source": "https://github.com/MioVisman/dirk/tree/visman"
|
"source": "https://github.com/MioVisman/dirk/tree/visman"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "miovisman/normemail",
|
||||||
|
"version": "dev-master",
|
||||||
|
"version_normalized": "9999999-dev",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/MioVisman/NormEmail.git",
|
||||||
|
"reference": "c582b1359adf1ee2efa38809e8827ed21138a9ac"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/MioVisman/NormEmail/zipball/c582b1359adf1ee2efa38809e8827ed21138a9ac",
|
||||||
|
"reference": "c582b1359adf1ee2efa38809e8827ed21138a9ac",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-intl": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": ">=5.6.0"
|
||||||
|
},
|
||||||
|
"time": "2019-12-24T15:42:43+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"MioVisman\\NormEmail\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Visman",
|
||||||
|
"email": "mio.visman@yandex.ru",
|
||||||
|
"homepage": "https://github.com/MioVisman"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Normalization of email for bans, for request cache to SFS or for checking the uniqueness of new users.",
|
||||||
|
"homepage": "https://github.com/MioVisman/NormEmail",
|
||||||
|
"keywords": [
|
||||||
|
"ban",
|
||||||
|
"canonical email",
|
||||||
|
"email",
|
||||||
|
"normalization"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "miovisman/parserus",
|
"name": "miovisman/parserus",
|
||||||
"version": "dev-master",
|
"version": "dev-master",
|
||||||
|
@ -72,7 +120,7 @@
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.4.0"
|
"php": ">=5.4.0"
|
||||||
},
|
},
|
||||||
"time": "2019-10-11 12:06:27",
|
"time": "2019-10-11T12:06:27+00:00",
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"installation-source": "dist",
|
"installation-source": "dist",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|
21
vendor/miovisman/normemail/LICENSE
vendored
Normal file
21
vendor/miovisman/normemail/LICENSE
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Visman
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
62
vendor/miovisman/normemail/README.md
vendored
Normal file
62
vendor/miovisman/normemail/README.md
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# NormEmail
|
||||||
|
|
||||||
|
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
```
|
||||||
|
composer require miovisman/normemail
|
||||||
|
```
|
||||||
|
|
||||||
|
## normalize() method
|
||||||
|
``` php
|
||||||
|
$nEmail = new MioVisman\NormEmail\NormEmail();
|
||||||
|
|
||||||
|
$email = $nEmail->normalize($email);
|
||||||
|
```
|
||||||
|
|
||||||
|
* ### Method does not validate email address
|
||||||
|
* ### Do not use normalized email to send emails
|
||||||
|
* Use a normalized email to check the ban or uniqueness of the email of a new user. Check on the normalized emails ;)
|
||||||
|
* The domain is lowercase (and in Punycode)
|
||||||
|
* The local part is lowercase unless otherwise specified
|
||||||
|
* The local part after the "+" is truncated (for Yahoo domains - after the "-")
|
||||||
|
|
||||||
|
```
|
||||||
|
// some string
|
||||||
|
ExampLe => example
|
||||||
|
exaMple.COM => example.com
|
||||||
|
.example.com => .example.com
|
||||||
|
@example.com => example.com
|
||||||
|
"example.com => "example.com
|
||||||
|
"USER+++NAME@EXAMpLE.com => "USER+++NAME@example.com
|
||||||
|
googlemail.com => gmail.com
|
||||||
|
pm.me => protonmail.com
|
||||||
|
yandex.tj => yandex.ru
|
||||||
|
ya.ru => yandex.ru
|
||||||
|
|
||||||
|
// Unicode
|
||||||
|
ПОЛЬЗОВАТЕЛЬ@домен.РУ => пользователь@xn--d1acufc.xn--p1ag
|
||||||
|
пользователь+тег@домен.ру => пользователь@xn--d1acufc.xn--p1ag
|
||||||
|
|
||||||
|
// Gmail
|
||||||
|
User.namE+tag@gmail.com => username@gmail.com
|
||||||
|
u.sern.ame+tag+tag+tag@googlemail.com => username@gmail.com
|
||||||
|
|
||||||
|
// Protonmail
|
||||||
|
u_s.e-rname+tag@pm.me => username@protonmail.com
|
||||||
|
user-name@protonmail.ch => username@protonmail.com
|
||||||
|
|
||||||
|
// Yahoo (.com, .ae, .at, ...)
|
||||||
|
username-tag@yahoo.com => username@yahoo.com
|
||||||
|
user+name-tag@yahoo.fr => user+name@yahoo.fr
|
||||||
|
|
||||||
|
// Yandex (13 domains)
|
||||||
|
user.name+tag@яндекс.рф => user-name@yandex.ru
|
||||||
|
user-name@yandex.com => user-name@yandex.ru
|
||||||
|
username@ya.ru => username@yandex.ru
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is under MIT license. Please see the [license file](LICENSE) for details.
|
25
vendor/miovisman/normemail/composer.json
vendored
Normal file
25
vendor/miovisman/normemail/composer.json
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "miovisman/normemail",
|
||||||
|
"description": "Normalization of email for bans, for request cache to SFS or for checking the uniqueness of new users.",
|
||||||
|
"keywords": ["email", "normalization", "canonical email", "ban"],
|
||||||
|
"homepage": "https://github.com/MioVisman/NormEmail",
|
||||||
|
"type": "library",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Visman",
|
||||||
|
"email": "mio.visman@yandex.ru",
|
||||||
|
"homepage": "https://github.com/MioVisman"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.6.0",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"ext-intl" : "*"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"MioVisman\\NormEmail\\": "src/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
201
vendor/miovisman/normemail/src/NormEmail.php
vendored
Normal file
201
vendor/miovisman/normemail/src/NormEmail.php
vendored
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2019 Visman. All rights reserved.
|
||||||
|
* @author Visman <mio.visman@yandex.ru>
|
||||||
|
* @link https://github.com/MioVisman/NormEmail
|
||||||
|
* @license https://opensource.org/licenses/MIT The MIT License (MIT)
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace MioVisman\NormEmail;
|
||||||
|
|
||||||
|
class NormEmail
|
||||||
|
{
|
||||||
|
const NO_RULE = 0;
|
||||||
|
const DOT = 1; // google
|
||||||
|
const DUM = 2; // protonmail
|
||||||
|
const DTOH = 4; // yandex
|
||||||
|
const HYPHEN = 8; // yahoo
|
||||||
|
const DONT_PLUS = 16; // someone?
|
||||||
|
const SENSITIVE = 32;
|
||||||
|
|
||||||
|
protected $rules = [
|
||||||
|
// Google https://support.google.com/mail/answer/7436150
|
||||||
|
'gmail.com' => self::DOT,
|
||||||
|
'googlemail.com' => 'gmail.com',
|
||||||
|
// Protonmail https://protonmail.com/support/knowledge-base/addresses-and-aliases/#comment-7913
|
||||||
|
// https://protonmail.com/support/knowledge-base/pm-me-addresses/
|
||||||
|
'protonmail.com' => self::DUM,
|
||||||
|
'protonmail.ch' => 'protonmail.com',
|
||||||
|
'pm.me' => 'protonmail.com',
|
||||||
|
// Yahoo https://help.yahoo.com/kb/SLN28338.html
|
||||||
|
// https://help.yahoo.com/kb/SLN2153.html
|
||||||
|
'yahoo.com' => self::HYPHEN,
|
||||||
|
'yahoo.ae' => self::HYPHEN,
|
||||||
|
'yahoo.com.ar' => self::HYPHEN,
|
||||||
|
'yahoo.at' => self::HYPHEN,
|
||||||
|
'yahoo.com.au' => self::HYPHEN,
|
||||||
|
'yahoo.be' => self::HYPHEN,
|
||||||
|
'yahoo.com.br' => self::HYPHEN,
|
||||||
|
'yahoo.ca' => self::HYPHEN,
|
||||||
|
'yahoo.ch' => self::HYPHEN,
|
||||||
|
'yahoo.com.co' => self::HYPHEN,
|
||||||
|
'yahoo.cz' => self::HYPHEN,
|
||||||
|
'yahoo.de' => self::HYPHEN,
|
||||||
|
'yahoo.dk' => self::HYPHEN,
|
||||||
|
'yahoo.es' => self::HYPHEN,
|
||||||
|
'yahoo.fi' => self::HYPHEN,
|
||||||
|
'yahoo.fr' => self::HYPHEN,
|
||||||
|
'yahoo.gr' => self::HYPHEN,
|
||||||
|
'yahoo.com.hk' => self::HYPHEN,
|
||||||
|
'yahoo.com.hr' => self::HYPHEN,
|
||||||
|
'yahoo.hu' => self::HYPHEN,
|
||||||
|
'yahoo.co.id' => self::HYPHEN,
|
||||||
|
'yahoo.ie' => self::HYPHEN,
|
||||||
|
'yahoo.co.il' => self::HYPHEN,
|
||||||
|
'yahoo.in' => self::HYPHEN,
|
||||||
|
'yahoo.co.in' => self::HYPHEN,
|
||||||
|
'yahoo.it' => self::HYPHEN,
|
||||||
|
'yahoo.co.jp' => self::HYPHEN,
|
||||||
|
'yahoo.com.my' => self::HYPHEN,
|
||||||
|
'yahoo.com.mx' => self::HYPHEN,
|
||||||
|
'yahoo.nl' => self::HYPHEN,
|
||||||
|
'yahoo.no' => self::HYPHEN,
|
||||||
|
'yahoo.co.nz' => self::HYPHEN,
|
||||||
|
'yahoo.com.ph' => self::HYPHEN,
|
||||||
|
'yahoo.pl' => self::HYPHEN,
|
||||||
|
'yahoo.pt' => self::HYPHEN,
|
||||||
|
'yahoo.ro' => self::HYPHEN,
|
||||||
|
'yahoo.ru' => self::HYPHEN,
|
||||||
|
'yahoo.se' => self::HYPHEN,
|
||||||
|
'yahoo.com.sg' => self::HYPHEN,
|
||||||
|
'yahoo.co.th' => self::HYPHEN,
|
||||||
|
'yahoo.com.tr' => self::HYPHEN,
|
||||||
|
'yahoo.com.tw' => self::HYPHEN,
|
||||||
|
'yahoo.co.uk' => self::HYPHEN,
|
||||||
|
'yahoo.com.vn' => self::HYPHEN,
|
||||||
|
'yahoo.co.za' => self::HYPHEN,
|
||||||
|
// Yandex https://habr.com/ru/company/yandex/blog/56866/
|
||||||
|
'yandex.ru' => self::DTOH,
|
||||||
|
'ya.ru' => 'yandex.ru',
|
||||||
|
# 'yandex.asia' => 'yandex.ru', // no MX
|
||||||
|
'yandex.az' => 'yandex.ru',
|
||||||
|
'yandex.by' => 'yandex.ru',
|
||||||
|
'yandex.com' => 'yandex.ru',
|
||||||
|
# 'yandex.de' => 'yandex.ru', // no MX
|
||||||
|
# 'yandex.dk' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.do' => 'yandex.ru', // empty
|
||||||
|
'yandex.ee' => 'yandex.ru',
|
||||||
|
# 'yandex.es' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.eu' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.ie' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.in' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.it' => 'yandex.ru', // no MX
|
||||||
|
'yandex.lt' => 'yandex.ru',
|
||||||
|
# 'yandex.lu' => 'yandex.ru', // empty
|
||||||
|
'yandex.lv' => 'yandex.ru',
|
||||||
|
'yandex.md' => 'yandex.ru',
|
||||||
|
# 'yandex.mobi' => 'yandex.ru', // no MX
|
||||||
|
# 'yandex.mx' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.net' => 'yandex.ru', // is not synonymous with ru? need self::DTOH?
|
||||||
|
# 'yandex.no' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.nu' => 'yandex.ru', // no MX
|
||||||
|
# 'yandex.org' => 'yandex.ru', // no MX
|
||||||
|
# 'yandex.pl' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.pt' => 'yandex.ru', // no MX
|
||||||
|
# 'yandex.qa' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.ro' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.rs' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.net.ru' => 'yandex.ru', // no MX
|
||||||
|
# 'yandex.com.ru' => 'yandex.ru', // no MX
|
||||||
|
# 'yandex.sk' => 'yandex.ru', // empty
|
||||||
|
# 'yandex.so' => 'yandex.ru', // empty
|
||||||
|
'yandex.tj' => 'yandex.ru',
|
||||||
|
'yandex.tm' => 'yandex.ru',
|
||||||
|
'yandex.ua' => 'yandex.ru',
|
||||||
|
# 'yandex.com.ua' => 'yandex.ru', // is not synonymous with ru? need self::DTOH?
|
||||||
|
'yandex.uz' => 'yandex.ru',
|
||||||
|
'xn--d1acpjx3f.xn--p1ai' => 'yandex.ru', // яндекс.рф
|
||||||
|
// Fastmail https://www.fastmail.com/help/receive/addressing.html
|
||||||
|
// https://www.fastmail.com/about/ourdomains/
|
||||||
|
// TODO: Make subdomain translation to the local part of the address
|
||||||
|
];
|
||||||
|
|
||||||
|
public function normalize($email)
|
||||||
|
{
|
||||||
|
if (false === ($pos = \strrpos($email, '@'))) {
|
||||||
|
$domain = $email;
|
||||||
|
$local = '';
|
||||||
|
} else {
|
||||||
|
$domain = \substr($email, $pos + 1);
|
||||||
|
$local = \substr($email, 0, $pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
$domain = \mb_strtolower($domain, 'UTF-8');
|
||||||
|
|
||||||
|
// TODO: Process the dot at the beginning of the domain for the ban of the domains array (ban by the domain name without the local part)
|
||||||
|
|
||||||
|
if ('[' !== $domain[0] && \preg_match('%[\x80-\xFF]%', $domain)) {
|
||||||
|
$parts = \explode('.', $domain);
|
||||||
|
foreach ($parts as &$part) {
|
||||||
|
$ascii = \idn_to_ascii($part, \IDNA_DEFAULT, \INTL_IDNA_VARIANT_UTS46);
|
||||||
|
if (false !== $ascii) {
|
||||||
|
$part = $ascii;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($part);
|
||||||
|
$domain = \implode('.', $parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
$rule = self::NO_RULE;
|
||||||
|
if (isset($this->rules[$domain])) {
|
||||||
|
$rule = $this->rules[$domain];
|
||||||
|
if (\is_string($rule)) {
|
||||||
|
$domain = $rule;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
if (isset($local[0]) && '"' !== $local[0]) {
|
||||||
|
if ($rule & self::HYPHEN) {
|
||||||
|
$symbol = '-';
|
||||||
|
} elseif ($rule & self::DONT_PLUS) {
|
||||||
|
$symbol = false;
|
||||||
|
} else {
|
||||||
|
$symbol = '+';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false !== $symbol) {
|
||||||
|
$pos = \strpos($local, $symbol);
|
||||||
|
if (false !== $pos) {
|
||||||
|
$local = \substr($local, 0, $pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rule & self::DOT) {
|
||||||
|
$local = \str_replace('.', '', $local);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rule & self::DUM) {
|
||||||
|
$local = \str_replace(['.', '_', '-'], '', $local);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rule & self::DTOH) {
|
||||||
|
$local = \str_replace('.', '-', $local);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! ($rule & self::SENSITIVE)) {
|
||||||
|
$local = \mb_strtolower($local, 'UTF-8');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('' == $local) {
|
||||||
|
return $domain; // '@myhost.com' --> 'myhost.com'
|
||||||
|
} else {
|
||||||
|
return $local . '@' . $domain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue