Merge pull request #1 from theunclehonnor/add-cyrillic-support

Added support for cyrillic characters in email
This commit is contained in:
Alexey 2022-05-06 11:25:39 +03:00 committed by GitHub
commit c2f7ea5767
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 46 additions and 14 deletions

View File

@ -3,7 +3,8 @@
"description": "Remove aliases from email and get primary email account", "description": "Remove aliases from email and get primary email account",
"type": "library", "type": "library",
"require": { "require": {
"php": "^7.0.0" "php": "^7.0.0",
"ext-mbstring": "*"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "6.5.14", "phpunit/phpunit": "6.5.14",

View File

@ -8,19 +8,25 @@ class Email implements EmailInterface
{ {
use EmailTrait; use EmailTrait;
public function __construct(string $email, bool $caseSensitive = false) const PATTERN_WITH_SUPPORT_CYRILLIC = '/^[a-zA-Zа-яА-Я0-9.!#$%&\'*+\\/=?^_`{|}~-]+@[a-zA-Zа-яА-Я0-9](?:[a-zA-Zа-яА-Я0-9-]{0,61}[a-zA-Zа-яА-Я0-9])?(?:\.[a-zA-Zа-яА-Я0-9](?:[a-zA-Zа-яА-Я0-9-]{0,61}[a-zA-Zа-яА-Я0-9])?)+$/u';
public function __construct(string $email, bool $caseSensitive = false, bool $cyrillicAllowed = false)
{ {
$this->validateEmail($email); $this->validateEmail($email, $cyrillicAllowed);
list($this->localPart, $this->domain) = explode('@', $email); list($this->localPart, $this->domain) = explode('@', $email);
if (!$caseSensitive) { if (!$caseSensitive) {
$this->localPart = strtolower($this->localPart); $this->localPart = mb_strtolower($this->localPart);
} }
$this->domain = strtolower($this->domain); $this->domain = mb_strtolower($this->domain);
} }
private function validateEmail(string $email) private function validateEmail(string $email, bool $cyrillicAllowed)
{ {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { if ($cyrillicAllowed && !preg_match(self::PATTERN_WITH_SUPPORT_CYRILLIC, $email)) {
throw new InvalidEmailException("Email '{$email}' is not valid!");
}
if (!$cyrillicAllowed && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidEmailException("Email '{$email}' is not valid!"); throw new InvalidEmailException("Email '{$email}' is not valid!");
} }
} }

View File

@ -127,7 +127,7 @@ class EditableEmailTest extends TestCase
$editable = new EditableEmail($email); $editable = new EditableEmail($email);
$new = $editable->lowerCaseLocalPartIf($condition); $new = $editable->lowerCaseLocalPartIf($condition);
$this->assertSame(!$condition, $editable === $new); $this->assertSame(!$condition, $editable === $new);
$this->assertSame($isLowerCase, strtolower($editable->getLocalPart()) === $new->getLocalPart()); $this->assertSame($isLowerCase, mb_strtolower($editable->getLocalPart()) === $new->getLocalPart());
$this->assertSame($email->getDomain(), $new->getDomain()); $this->assertSame($email->getDomain(), $new->getDomain());
} }

View File

@ -18,18 +18,20 @@ class EmailTest extends TestCase
* @param string $localPart * @param string $localPart
* @param string $domain * @param string $domain
* @param bool $caseSensitive * @param bool $caseSensitive
* @param bool $cyrillicAllowed
*/ */
public function testConstructor( public function testConstructor(
string $email, string $email,
bool $expectedException, bool $expectedException,
string $localPart = '', string $localPart = '',
string $domain = '', string $domain = '',
bool $caseSensitive = false bool $caseSensitive = false,
bool $cyrillicAllowed = false
) { ) {
if ($expectedException) { if ($expectedException) {
$this->expectException(InvalidEmailException::class); $this->expectException(InvalidEmailException::class);
} }
$object = new Email($email, $caseSensitive); $object = new Email($email, $caseSensitive, $cyrillicAllowed);
$this->assertSame($localPart, $object->getLocalPart()); $this->assertSame($localPart, $object->getLocalPart());
$this->assertSame($domain, $object->getDomain()); $this->assertSame($domain, $object->getDomain());
} }
@ -41,6 +43,13 @@ class EmailTest extends TestCase
['.johndoe@example.com', true], ['.johndoe@example.com', true],
['Jane.Doe@Example.COM', false, 'Jane.Doe', 'example.com', true], ['Jane.Doe@Example.COM', false, 'Jane.Doe', 'example.com', true],
['Jane.Doe@Example.COM', false, 'jane.doe', 'example.com'], ['Jane.Doe@Example.COM', false, 'jane.doe', 'example.com'],
// Cyrillic use
['тест тест@example.com', true],
['.тест@example.com', true],
['Тест.Тест@Example.COM', false, 'Тест.Тест', 'example.com', true, true],
['Тест.Тест@Example.COM', false, 'тест.тест', 'example.com', false, true],
['Тест.Тест@Тест.РУ', false, 'Тест.Тест', 'тест.ру', true, true],
['Тест.Тест@Тест.РУ', false, 'тест.тест', 'тест.ру', false, true],
]; ];
} }
} }

View File

@ -15,10 +15,11 @@ class MailRuTest extends TestCase
* *
* @param string $inputEmail * @param string $inputEmail
* @param string $outputEmail * @param string $outputEmail
* @param bool $cyrillicAllowed
*/ */
public function testGetPrimaryEmail(string $inputEmail, string $outputEmail) public function testGetPrimaryEmail(string $inputEmail, string $outputEmail, bool $cyrillicAllowed = false)
{ {
$this->assertEquals($outputEmail, (new MailRu())->getPrimaryEmail(new Email($inputEmail))); $this->assertEquals($outputEmail, (new MailRu())->getPrimaryEmail(new Email($inputEmail, false, $cyrillicAllowed)));
} }
public function providerGetPrimaryEmail() : array public function providerGetPrimaryEmail() : array
@ -27,6 +28,10 @@ class MailRuTest extends TestCase
['foobar@MAIL.RU', 'foobar@mail.ru'], ['foobar@MAIL.RU', 'foobar@mail.ru'],
['fOObar@MaiL.Ru', 'foobar@mail.ru'], ['fOObar@MaiL.Ru', 'foobar@mail.ru'],
['foobar+alias@mail.ru', 'foobar@mail.ru'], ['foobar+alias@mail.ru', 'foobar@mail.ru'],
// Cyrillic use
['иванов@MAIL.RU', 'иванов@mail.ru', true],
['иванОВ@MaiL.Ru', 'иванов@mail.ru', true],
['иванов+alias@mail.ru', 'иванов@mail.ru', true],
]; ];
} }

View File

@ -15,10 +15,11 @@ class YandexRuTest extends TestCase
* *
* @param string $inputEmail * @param string $inputEmail
* @param string $outputEmail * @param string $outputEmail
* @param bool $cyrillicAllowed
*/ */
public function testGetPrimaryEmail(string $inputEmail, string $outputEmail) public function testGetPrimaryEmail(string $inputEmail, string $outputEmail, bool $cyrillicAllowed = false)
{ {
$this->assertEquals($outputEmail, (new YandexRu())->getPrimaryEmail(new Email($inputEmail))); $this->assertEquals($outputEmail, (new YandexRu())->getPrimaryEmail(new Email($inputEmail, false, $cyrillicAllowed)));
} }
public function providerGetPrimaryEmail() : array public function providerGetPrimaryEmail() : array
@ -33,6 +34,16 @@ class YandexRuTest extends TestCase
['foobar@yandex.by', 'foobar@yandex.ru'], ['foobar@yandex.by', 'foobar@yandex.ru'],
['foobar@yandex.kz', 'foobar@yandex.ru'], ['foobar@yandex.kz', 'foobar@yandex.ru'],
['foobar@yandex.ua', 'foobar@yandex.ru'], ['foobar@yandex.ua', 'foobar@yandex.ru'],
// Cyrillic use
['иванов@YANDEX.RU', 'иванов@yandex.ru', true],
['иванОВ@YAndEX.ru', 'иванов@yandex.ru', true],
['иванов+alias@yandex.ru', 'иванов@yandex.ru', true],
['ИвановИван@ya.ru', 'ивановиван@yandex.ru', true],
['Иванов.Иван@ya.ru', 'иванов-иван@yandex.ru', true],
['иванов@yandex.com', 'иванов@yandex.ru', true],
['иванов@yandex.by', 'иванов@yandex.ru', true],
['иванов@yandex.kz', 'иванов@yandex.ru', true],
['иванов@yandex.ua', 'иванов@yandex.ru', true],
]; ];
} }