diff --git a/composer.json b/composer.json index b683a16..eba75d0 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,8 @@ "description": "Remove aliases from email and get primary email account", "type": "library", "require": { - "php": "^7.0.0" + "php": "^7.0.0", + "ext-mbstring": "*" }, "require-dev": { "phpunit/phpunit": "6.5.14", diff --git a/src/Emails/Email.php b/src/Emails/Email.php index f94b955..cab0134 100644 --- a/src/Emails/Email.php +++ b/src/Emails/Email.php @@ -8,19 +8,25 @@ class Email implements EmailInterface { 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); 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!"); } } diff --git a/tests/Emails/EditableEmailTest.php b/tests/Emails/EditableEmailTest.php index 8049bd1..cf31282 100644 --- a/tests/Emails/EditableEmailTest.php +++ b/tests/Emails/EditableEmailTest.php @@ -127,7 +127,7 @@ class EditableEmailTest extends TestCase $editable = new EditableEmail($email); $new = $editable->lowerCaseLocalPartIf($condition); $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()); } diff --git a/tests/Emails/EmailTest.php b/tests/Emails/EmailTest.php index c559de7..0939909 100644 --- a/tests/Emails/EmailTest.php +++ b/tests/Emails/EmailTest.php @@ -18,18 +18,20 @@ class EmailTest extends TestCase * @param string $localPart * @param string $domain * @param bool $caseSensitive + * @param bool $cyrillicAllowed */ public function testConstructor( string $email, bool $expectedException, string $localPart = '', string $domain = '', - bool $caseSensitive = false + bool $caseSensitive = false, + bool $cyrillicAllowed = false ) { if ($expectedException) { $this->expectException(InvalidEmailException::class); } - $object = new Email($email, $caseSensitive); + $object = new Email($email, $caseSensitive, $cyrillicAllowed); $this->assertSame($localPart, $object->getLocalPart()); $this->assertSame($domain, $object->getDomain()); } @@ -41,6 +43,13 @@ class EmailTest extends TestCase ['.johndoe@example.com', true], ['Jane.Doe@Example.COM', false, 'Jane.Doe', 'example.com', true], ['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], ]; } } \ No newline at end of file diff --git a/tests/Services/MailRuTest.php b/tests/Services/MailRuTest.php index 13dd81c..e80dc9b 100644 --- a/tests/Services/MailRuTest.php +++ b/tests/Services/MailRuTest.php @@ -15,10 +15,11 @@ class MailRuTest extends TestCase * * @param string $inputEmail * @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 @@ -27,6 +28,10 @@ class MailRuTest extends TestCase ['foobar@MAIL.RU', 'foobar@mail.ru'], ['fOObar@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], ]; } diff --git a/tests/Services/YandexRuTest.php b/tests/Services/YandexRuTest.php index 797f7fd..9a88120 100644 --- a/tests/Services/YandexRuTest.php +++ b/tests/Services/YandexRuTest.php @@ -15,10 +15,11 @@ class YandexRuTest extends TestCase * * @param string $inputEmail * @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 @@ -33,6 +34,16 @@ class YandexRuTest extends TestCase ['foobar@yandex.by', 'foobar@yandex.ru'], ['foobar@yandex.kz', '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], ]; }